Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into feat/custom-token-reg…
Browse files Browse the repository at this point in the history
…istars
  • Loading branch information
Foivos committed Oct 30, 2023
2 parents de5bcda + ed9856a commit 6147bf3
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 7 deletions.
104 changes: 104 additions & 0 deletions contracts/test/utils/FlowLimitTestLiveNetwork.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IFlowLimit } from '../../interfaces/IFlowLimit.sol';

contract FlowLimitTestLiveNetwork is IFlowLimit {
uint256 internal constant FLOW_LIMIT_SLOT = 0x201b7a0b7c19aaddc4ce9579b7df8d2db123805861bc7763627f13e04d8af42f;
uint256 internal constant PREFIX_FLOW_OUT_AMOUNT = uint256(keccak256('flow-out-amount'));
uint256 internal constant PREFIX_FLOW_IN_AMOUNT = uint256(keccak256('flow-in-amount'));

uint256 internal constant EPOCH_TIME = 60;

function getFlowLimit() public view returns (uint256 flowLimit) {
assembly {
flowLimit := sload(FLOW_LIMIT_SLOT)
}
}

function _setFlowLimit(uint256 flowLimit) internal {
assembly {
sstore(FLOW_LIMIT_SLOT, flowLimit)
}

emit FlowLimitSet(flowLimit);
}

function _getFlowOutSlot(uint256 epoch) internal pure returns (uint256 slot) {
slot = uint256(keccak256(abi.encode(PREFIX_FLOW_OUT_AMOUNT, epoch)));
}

function _getFlowInSlot(uint256 epoch) internal pure returns (uint256 slot) {
slot = uint256(keccak256(abi.encode(PREFIX_FLOW_IN_AMOUNT, epoch)));
}

function getFlowOutAmount() external view returns (uint256 flowOutAmount) {
uint256 epoch = block.timestamp / EPOCH_TIME;
uint256 slot = _getFlowOutSlot(epoch);

assembly {
flowOutAmount := sload(slot)
}
}

function getFlowInAmount() external view returns (uint256 flowInAmount) {
uint256 epoch = block.timestamp / EPOCH_TIME;
uint256 slot = _getFlowInSlot(epoch);

assembly {
flowInAmount := sload(slot)
}
}

function _addFlow(uint256 flowLimit, uint256 slotToAdd, uint256 slotToCompare, uint256 flowAmount) internal {
uint256 flowToAdd;
uint256 flowToCompare;

assembly {
flowToAdd := sload(slotToAdd)
flowToCompare := sload(slotToCompare)
}

if (flowToAdd + flowAmount > flowToCompare + flowLimit) revert FlowLimitExceeded();
if (flowAmount > flowLimit) revert FlowLimitExceeded();

assembly {
sstore(slotToAdd, add(flowToAdd, flowAmount))
}
}

function _addFlowOut(uint256 flowOutAmount) internal {
uint256 flowLimit = getFlowLimit();
if (flowLimit == 0) return;

uint256 epoch = block.timestamp / EPOCH_TIME;
uint256 slotToAdd = _getFlowOutSlot(epoch);
uint256 slotToCompare = _getFlowInSlot(epoch);

_addFlow(flowLimit, slotToAdd, slotToCompare, flowOutAmount);
}

function _addFlowIn(uint256 flowInAmount) internal {
uint256 flowLimit = getFlowLimit();
if (flowLimit == 0) return;

uint256 epoch = block.timestamp / EPOCH_TIME;
uint256 slotToAdd = _getFlowInSlot(epoch);
uint256 slotToCompare = _getFlowOutSlot(epoch);

_addFlow(flowLimit, slotToAdd, slotToCompare, flowInAmount);
}

function setFlowLimit(uint256 flowLimit) external {
_setFlowLimit(flowLimit);
}

function addFlowIn(uint256 flowInAmount) external {
_addFlowIn(flowInAmount);
}

function addFlowOut(uint256 flowOutAmount) external {
_addFlowOut(flowOutAmount);
}
}
21 changes: 14 additions & 7 deletions test/UtilsTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const { Wallet, Contract } = ethers;
const { AddressZero } = ethers.constants;
const { defaultAbiCoder, arrayify, toUtf8Bytes, hexlify } = ethers.utils;
const { expect } = chai;
const { getRandomBytes32, expectRevert } = require('./utils');
const { getRandomBytes32, expectRevert, isHardhat, waitFor } = require('./utils');
const { deployContract } = require('../scripts/deploy');

const ImplemenationTest = require('../artifacts/contracts/test/utils/ImplementationTest.sol/ImplementationTest.json');
Expand Down Expand Up @@ -207,18 +207,25 @@ describe('ExpressCallHandler', () => {

describe('FlowLimit', async () => {
let test;
const flowLimit = 5;
const flowLimit = isHardhat ? 5 : 2;

before(async () => {
test = await deployContract(ownerWallet, 'FlowLimitTest');
test = isHardhat
? await deployContract(ownerWallet, 'FlowLimitTest')
: await deployContract(ownerWallet, 'FlowLimitTestLiveNetwork');
});

async function nextEpoch() {
const latest = Number(await time.latest());
const epoch = 6 * 3600;
const next = (Math.floor(latest / epoch) + 1) * epoch;
const epoch = isHardhat ? 6 * 3600 : 60;

await time.increaseTo(next);
if (isHardhat) {
const latest = Number(await time.latest());
const next = (Math.floor(latest / epoch) + 1) * epoch;

await time.increaseTo(next);
} else {
await waitFor(epoch);
}
}

it('Should calculate hardcoded constants correctly', async () => {
Expand Down
13 changes: 13 additions & 0 deletions test/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const getGasOptions = () => {
return network.config.blockGasLimit ? { gasLimit: network.config.blockGasLimit.toString() } : { gasLimit: 5e6 }; // defaults to 5M gas for revert tests to work correctly
};

const isHardhat = network.name === 'hardhat';

const expectRevert = async (txFunc, contract, error) => {
if (network.config.skipRevertTests) {
await expect(txFunc(getGasOptions())).to.be.reverted;
Expand All @@ -18,6 +20,15 @@ const expectRevert = async (txFunc, contract, error) => {
}
};

const waitFor = async (timeDelay) => {
if (isHardhat) {
await network.provider.send('evm_increaseTime', [timeDelay]);
await network.provider.send('evm_mine');
} else {
await new Promise((resolve) => setTimeout(resolve, timeDelay * 1000));
}
};

const getChainId = () => {
return network.config.chainId;
};
Expand All @@ -26,5 +37,7 @@ module.exports = {
getRandomBytes32,
getChainId,
getGasOptions,
isHardhat,
expectRevert,
waitFor,
};

0 comments on commit 6147bf3

Please sign in to comment.