diff --git a/packages/protocol/contracts-0.8/common/GasPriceMinimum.sol b/packages/protocol/contracts-0.8/common/GasPriceMinimum.sol index b2d0e73c0c0..f09dc6f8859 100644 --- a/packages/protocol/contracts-0.8/common/GasPriceMinimum.sol +++ b/packages/protocol/contracts-0.8/common/GasPriceMinimum.sol @@ -9,8 +9,6 @@ import "../../contracts/common/interfaces/ICeloVersionedContract.sol"; import "../../contracts/common/FixidityLib.sol"; import "./UsingRegistry.sol"; import "../../contracts/stability/interfaces/ISortedOracles.sol"; -import "@openzeppelin/contracts8/utils/math/Math.sol"; - /** * @title Stores and provides gas price minimum for various currencies. @@ -40,7 +38,6 @@ contract GasPriceMinimum is FixidityLib.Fraction public adjustmentSpeed; uint256 public baseFeeOpCodeActivationBlock; - uint256 public constant ABSOLUTE_MINIMAL_GAS_PRICE = 1; /** * @notice Sets initialized == true on implementation contracts @@ -153,7 +150,12 @@ contract GasPriceMinimum is } } - function _getGasPriceMinimum(address tokenAddress) private view returns (uint256) { + /** + * @notice Retrieve the current gas price minimum for a currency. + * @param tokenAddress The currency the gas price should be in (defaults to gold). + * @return current gas price minimum in the requested currency + */ + function getGasPriceMinimum(address tokenAddress) external view returns (uint256) { if ( tokenAddress == address(0) || tokenAddress == registry.getAddressForOrDie(GOLD_TOKEN_REGISTRY_ID) @@ -170,22 +172,6 @@ contract GasPriceMinimum is } } - - /** - * @notice Retrieve the current gas price minimum for a currency. - * When caled for 0x0 or Celo address, it returns gasPriceMinimum(). - * For other addresses it returns gasPriceMinimum() mutiplied by - * the SortedOracles median of the token. It does not check tokenAddress is a valid fee currency. - * this function will never returns values less than ABSOLUTE_MINIMAL_GAS_PRICE. - * If Oracle rate doesn't exist, it returns ABSOLUTE_MINIMAL_GAS_PRICE. - * @dev This functions assumes one unit of token has 18 digits. - * @param tokenAddress The currency the gas price should be in (defaults to Celo). - * @return current gas price minimum in the requested currency - */ - function getGasPriceMinimum(address tokenAddress) external view returns (uint256) { - return Math.max(_getGasPriceMinimum(tokenAddress), ABSOLUTE_MINIMAL_GAS_PRICE); - } - /** * @notice Adjust the gas price minimum based on governable parameters * and block congestion. diff --git a/packages/protocol/contracts/stability/test/MockSortedOracles.sol b/packages/protocol/contracts/stability/test/MockSortedOracles.sol index f3faeb0e55e..6b35d2939bc 100644 --- a/packages/protocol/contracts/stability/test/MockSortedOracles.sol +++ b/packages/protocol/contracts/stability/test/MockSortedOracles.sol @@ -1,4 +1,4 @@ -pragma solidity >=0.5.13 <0.9.0; +pragma solidity ^0.5.13; /** * @title A mock SortedOracles for testing. @@ -21,7 +21,7 @@ contract MockSortedOracles { function setMedianTimestampToNow(address token) external { // solhint-disable-next-line not-rely-on-time - medianTimestamp[token] = uint128(block.timestamp); + medianTimestamp[token] = uint128(now); } function setNumRates(address token, uint256 rate) external { diff --git a/packages/protocol/foundry.toml b/packages/protocol/foundry.toml index 4352cfb7718..5d730ebffb3 100644 --- a/packages/protocol/foundry.toml +++ b/packages/protocol/foundry.toml @@ -12,15 +12,10 @@ remappings = [ 'forge-std/=lib/celo-foundry/lib/forge-std/src/', 'ds-test/=lib/celo-foundry/lib/forge-std/lib/ds-test/src/', 'celo-foundry/=lib/celo-foundry/src/', - '@summa-tx/memview.sol/=lib/memview.sol', - 'celo-foundry-8/=lib/celo-foundry-8/src/', - 'forge-std-8/=lib/celo-foundry-8/lib/forge-std/src/', - '@celo-contracts-8=contracts-0.8/', - '@openzeppelin/contracts8/=lib/openzeppelin-contracts8/contracts/', - '@celo-contracts=contracts/' + '@summa-tx/memview.sol/=lib/memview.sol' ] no_match_contract = "RandomTest" no_match_path = "contracts/common/libraries/test/BLS12Passthrough.sol" # tested from celo-blockain repo -# See more config options https://github.com/foundry-rs/foundry/tree/master/config \ No newline at end of file +# See more config options https://github.com/foundry-rs/foundry/tree/master/config diff --git a/packages/protocol/test/common/feecurrencywhitelist.ts b/packages/protocol/test/common/feecurrencywhitelist.ts new file mode 100644 index 00000000000..6da1a5cf74b --- /dev/null +++ b/packages/protocol/test/common/feecurrencywhitelist.ts @@ -0,0 +1,75 @@ +import { assertTransactionRevertWithReason } from '@celo/protocol/lib/test-utils' +import { FeeCurrencyWhitelistContract, FeeCurrencyWhitelistInstance } from 'types' + +const FeeCurrencyWhitelist: FeeCurrencyWhitelistContract = artifacts.require('FeeCurrencyWhitelist') + +contract('FeeCurrencyWhitelist', (accounts: string[]) => { + let feeCurrencyWhitelist: FeeCurrencyWhitelistInstance + + const aTokenAddress = '0x000000000000000000000000000000000000ce10' + + const nonOwner = accounts[1] + + beforeEach(async () => { + feeCurrencyWhitelist = await FeeCurrencyWhitelist.new(true) + await feeCurrencyWhitelist.initialize() + }) + + describe('#initialize()', () => { + it('should have set the owner', async () => { + const owner: string = await feeCurrencyWhitelist.owner() + assert.equal(owner, accounts[0]) + }) + + it('should not be callable again', async () => { + await assertTransactionRevertWithReason( + feeCurrencyWhitelist.initialize(), + 'contract already initialized' + ) + }) + }) + + describe('#addToken()', () => { + it('should allow the owner to add a token', async () => { + await feeCurrencyWhitelist.addToken(aTokenAddress) + const tokens = await feeCurrencyWhitelist.getWhitelist() + assert.sameMembers(tokens, [aTokenAddress]) + }) + + it('should not allow a non-owner to add a token', async () => { + await assertTransactionRevertWithReason( + feeCurrencyWhitelist.addToken(aTokenAddress, { from: nonOwner }), + 'Ownable: caller is not the owner' + ) + }) + }) + + describe('Removing', () => { + beforeEach(async () => { + await feeCurrencyWhitelist.addToken(aTokenAddress) + await feeCurrencyWhitelist.addToken(accounts[0]) + await feeCurrencyWhitelist.addToken(accounts[1]) + }) + + describe('#removeToken()', () => { + it('Removes from a big list', async () => { + await feeCurrencyWhitelist.removeToken(accounts[0], 1) + assert.sameMembers(await feeCurrencyWhitelist.getWhitelist(), [aTokenAddress, accounts[1]]) + }) + + it("Doesn't remove if the index is wrong", async () => { + await assertTransactionRevertWithReason( + feeCurrencyWhitelist.removeToken(accounts[0], 0), + 'Index does not match.' + ) + }) + + it('should not allow a non-owner to remove Mento token', async () => { + await assertTransactionRevertWithReason( + feeCurrencyWhitelist.removeToken(accounts[0], 0, { from: nonOwner }), + 'Ownable: caller is not the owner.' + ) + }) + }) + }) +})