Skip to content

Commit

Permalink
feat: added support for the sdk roles contract instead of custom role…
Browse files Browse the repository at this point in the history
…s definitions (#128)

* Added roles, tests pending

* fix: tests

* Added some tests and fixed constants

* made lint happy

* Chnaged roles constants to enum to make slither happy

* Fixed tests

* Added getter for distributor and opearator.

* made lint happy

* fixed a spelling error

* update for the new roles functions

* update sdk

* updage to newest sdk

* made lint happy

* addressed a comment

* removed unused test files

* we actually need those.

---------

Co-authored-by: Dean Amiel <[email protected]>
  • Loading branch information
Foivos and Dean Amiel authored Oct 31, 2023
1 parent ee6b647 commit ceade4a
Show file tree
Hide file tree
Showing 22 changed files with 303 additions and 230 deletions.
4 changes: 2 additions & 2 deletions contracts/interchain-token-service/InterchainTokenService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ contract InterchainTokenService is
* @param tokenIds an array of the token Ids of the tokenManagers to set the flow limit of.
* @param flowLimits the flowLimits to set
*/
function setFlowLimits(bytes32[] calldata tokenIds, uint256[] calldata flowLimits) external onlyOperator {
function setFlowLimits(bytes32[] calldata tokenIds, uint256[] calldata flowLimits) external onlyRole(uint8(Roles.OPERATOR)) {
uint256 length = tokenIds.length;
if (length != flowLimits.length) revert LengthMismatch();
for (uint256 i; i < length; ++i) {
Expand All @@ -518,7 +518,7 @@ contract InterchainTokenService is
\****************/

function _setup(bytes calldata params) internal override {
_setOperator(params.toAddress());
_addOperator(params.toAddress());
}

function _sanitizeTokenManagerImplementation(
Expand Down
20 changes: 7 additions & 13 deletions contracts/interfaces/IDistributable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,6 @@
pragma solidity ^0.8.0;

interface IDistributable {
error NotDistributor();
error NotProposedDistributor();

event DistributorshipTransferred(address indexed distributor);
event DistributorshipTransferStarted(address indexed distributor);

/**
* @notice Get the address of the distributor
* @return distributor_ of the distributor
*/
function distributor() external view returns (address distributor_);

/**
* @notice Change the distributor of the contract
* @dev Can only be called by the current distributor
Expand All @@ -33,5 +21,11 @@ interface IDistributable {
* @notice Accept a change of the distributor of the contract
* @dev Can only be called by the proposed distributor
*/
function acceptDistributorship() external;
function acceptDistributorship(address fromDistributor) external;

/**
* @notice Query if an address is a distributor
* @param addr the address to query for
*/
function isDistributor(address addr) external view returns (bool);
}
20 changes: 7 additions & 13 deletions contracts/interfaces/IOperatable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,6 @@
pragma solidity ^0.8.0;

interface IOperatable {
error NotOperator();
error NotProposedOperator();

event OperatorshipTransferred(address indexed operator);
event OperatorChangeProposed(address indexed operator);

/**
* @notice Get the address of the operator
* @return operator_ of the operator
*/
function operator() external view returns (address operator_);

/**
* @notice Change the operator of the contract
* @dev Can only be called by the current operator
Expand All @@ -33,5 +21,11 @@ interface IOperatable {
* @notice Accept a proposed change of operatorship
* @dev Can only be called by the proposed operator
*/
function acceptOperatorship() external;
function acceptOperatorship(address fromOperator) external;

/**
* @notice Query if an address is a operator
* @param addr the address to query for
*/
function isOperator(address addr) external view returns (bool);
}
3 changes: 3 additions & 0 deletions contracts/interfaces/ITokenManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ interface ITokenManager is ITokenManagerType, IOperatable, IFlowLimit, IImplemen
error TakeTokenFailed();
error GiveTokenFailed();
error NotToken();
error ZeroAddress();
error AlreadyFlowLimiter(address flowLimiter);
error NotFlowLimiter(address flowLimiter);

/**
* @notice A function that returns the token id.
Expand Down
6 changes: 3 additions & 3 deletions contracts/test/FeeOnTransferTokenTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ contract FeeOnTransferTokenTest is InterchainToken, Distributable, IERC20Mintabl
name = name_;
symbol = symbol_;
decimals = decimals_;
_setDistributor(msg.sender);
_addDistributor(msg.sender);
tokenManager_ = ITokenManager(tokenManagerAddress);
}

Expand Down Expand Up @@ -50,11 +50,11 @@ contract FeeOnTransferTokenTest is InterchainToken, Distributable, IERC20Mintabl
tokenManagerRequiresApproval_ = requiresApproval;
}

function mint(address account, uint256 amount) external onlyDistributor {
function mint(address account, uint256 amount) external onlyRole(uint8(Roles.DISTRIBUTOR)) {
_mint(account, amount);
}

function burn(address account, uint256 amount) external onlyDistributor {
function burn(address account, uint256 amount) external onlyRole(uint8(Roles.DISTRIBUTOR)) {
_burn(account, amount);
}

Expand Down
10 changes: 2 additions & 8 deletions contracts/test/HardCodedConstantsTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ contract TestTokenManager is TokenManagerLiquidityPool {
contract TestDistributable is Distributable {
string public constant NAME = 'TestDistributable';

constructor() {
require(DISTRIBUTOR_SLOT == uint256(keccak256('distributor')) - 1, 'invalid constant');
require(PROPOSED_DISTRIBUTOR_SLOT == uint256(keccak256('proposed-distributor')) - 1, 'invalid constant');
}
constructor() {}
}

contract TestFlowLimit is FlowLimit {
Expand All @@ -46,10 +43,7 @@ contract TestNoReEntrancy is NoReEntrancy {
contract TestOperatable is Operatable {
string public constant NAME = 'TestOperatable';

constructor() {
require(OPERATOR_SLOT == uint256(keccak256('operator')) - 1, 'invalid constant');
require(PROPOSED_OPERATOR_SLOT == uint256(keccak256('proposed-operator')) - 1, 'invalid constant');
}
constructor() {}
}

contract TestPausable is Pausable {
Expand Down
6 changes: 3 additions & 3 deletions contracts/test/InterchainTokenTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ contract InterchainTokenTest is InterchainToken, Distributable, IERC20MintableBu
name = name_;
symbol = symbol_;
decimals = decimals_;
_setDistributor(msg.sender);
_addDistributor(msg.sender);
tokenManager_ = ITokenManager(tokenManagerAddress);
}

Expand Down Expand Up @@ -49,11 +49,11 @@ contract InterchainTokenTest is InterchainToken, Distributable, IERC20MintableBu
tokenManagerRequiresApproval_ = requiresApproval;
}

function mint(address account, uint256 amount) external onlyDistributor {
function mint(address account, uint256 amount) external onlyRole(uint8(Roles.DISTRIBUTOR)) {
_mint(account, amount);
}

function burn(address account, uint256 amount) external onlyDistributor {
function burn(address account, uint256 amount) external onlyRole(uint8(Roles.DISTRIBUTOR)) {
_burn(account, amount);
}

Expand Down
15 changes: 4 additions & 11 deletions contracts/test/InvalidStandardizedToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,6 @@ contract InvalidStandardizedToken is IERC20MintableBurnable, InterchainToken, ER

bytes32 private constant CONTRACT_ID = keccak256('invalid-standardized-token');

modifier onlyDistributorOrTokenManager() {
if (msg.sender != tokenManager_) {
if (msg.sender != distributor()) revert NotDistributor();
}

_;
}

/**
* @notice Getter for the contract id.
*/
Expand Down Expand Up @@ -62,7 +54,8 @@ contract InvalidStandardizedToken is IERC20MintableBurnable, InterchainToken, ER
tokenManager_ = tokenManagerAddress;
name = tokenName;

_setDistributor(distributor_);
_addDistributor(distributor_);
_addDistributor(tokenManagerAddress);
_setNameHash(tokenName);
}
{
Expand All @@ -82,7 +75,7 @@ contract InvalidStandardizedToken is IERC20MintableBurnable, InterchainToken, ER
* @param account The address that will receive the minted tokens
* @param amount The amount of tokens to mint
*/
function mint(address account, uint256 amount) external onlyDistributorOrTokenManager {
function mint(address account, uint256 amount) external onlyRole(uint8(Roles.DISTRIBUTOR)) {
_mint(account, amount);
}

Expand All @@ -92,7 +85,7 @@ contract InvalidStandardizedToken is IERC20MintableBurnable, InterchainToken, ER
* @param account The address that will have its tokens burnt
* @param amount The amount of tokens to burn
*/
function burn(address account, uint256 amount) external onlyDistributorOrTokenManager {
function burn(address account, uint256 amount) external onlyRole(uint8(Roles.DISTRIBUTOR)) {
_burn(account, amount);
}
}
8 changes: 6 additions & 2 deletions contracts/test/utils/DistributableTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ contract DistributableTest is Distributable {
uint256 public nonce;

constructor(address distributor) {
_setDistributor(distributor);
_addDistributor(distributor);
}

function testDistributable() external onlyDistributor {
function testDistributable() external onlyRole(uint8(Roles.DISTRIBUTOR)) {
nonce++;
}

function getDistributorRole() external pure returns (uint8) {
return uint8(Roles.DISTRIBUTOR);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ contract OperatorableTest is Operatable {
uint256 public nonce;

constructor(address operator) {
_setOperator(operator);
_addOperator(operator);
}

function testOperatorable() external onlyOperator {
function testOperatorable() external onlyRole(uint8(Roles.OPERATOR)) {
nonce++;
}

function getOperatorRole() external pure returns (uint8) {
return uint8(Roles.OPERATOR);
}
}
15 changes: 4 additions & 11 deletions contracts/token-implementations/StandardizedToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,6 @@ contract StandardizedToken is InterchainToken, ERC20Permit, Implementation, Dist

bytes32 private constant CONTRACT_ID = keccak256('standardized-token');

modifier onlyDistributorOrTokenManager() {
if (msg.sender != tokenManager_) {
if (msg.sender != distributor()) revert NotDistributor();
}

_;
}

/**
* @notice Getter for the contract id.
*/
Expand Down Expand Up @@ -71,7 +63,8 @@ contract StandardizedToken is InterchainToken, ERC20Permit, Implementation, Dist
tokenManager_ = tokenManagerAddress;
name = tokenName;

_setDistributor(distributor_);
_addDistributor(distributor_);
_addDistributor(tokenManagerAddress);
_setNameHash(tokenName);
}
{
Expand All @@ -91,7 +84,7 @@ contract StandardizedToken is InterchainToken, ERC20Permit, Implementation, Dist
* @param account The address that will receive the minted tokens
* @param amount The amount of tokens to mint
*/
function mint(address account, uint256 amount) external onlyDistributorOrTokenManager {
function mint(address account, uint256 amount) external onlyRole(uint8(Roles.DISTRIBUTOR)) {
_mint(account, amount);
}

Expand All @@ -101,7 +94,7 @@ contract StandardizedToken is InterchainToken, ERC20Permit, Implementation, Dist
* @param account The address that will have its tokens burnt
* @param amount The amount of tokens to burn
*/
function burn(address account, uint256 amount) external onlyDistributorOrTokenManager {
function burn(address account, uint256 amount) external onlyRole(uint8(Roles.DISTRIBUTOR)) {
_burn(account, amount);
}
}
30 changes: 27 additions & 3 deletions contracts/token-manager/TokenManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ abstract contract TokenManager is ITokenManager, Operatable, FlowLimit, Implemen
operator_ = operatorBytes.toAddress();
}

_setOperator(operator_);
_addAccountRoles(operator_, (1 << uint8(Roles.FLOW_LIMITER)) | (1 << uint8(Roles.OPERATOR)));
_setup(params);
}

Expand Down Expand Up @@ -197,10 +197,34 @@ abstract contract TokenManager is ITokenManager, Operatable, FlowLimit, Implemen
}

/**
* @notice This function sets the flow limit for this TokenManager. Can only be called by the operator.
* @notice This function adds a flow limiter for this TokenManager. Can only be called by the operator.
* @param flowLimiter the address of the new flow limiter.
*/
function addFlowLimiter(address flowLimiter) external onlyRole(uint8(Roles.OPERATOR)) {
if (flowLimiter == address(0)) revert ZeroAddress();

if (hasRole(flowLimiter, uint8(Roles.FLOW_LIMITER))) revert AlreadyFlowLimiter(flowLimiter);

_addRole(flowLimiter, uint8(Roles.FLOW_LIMITER));
}

/**
* @notice This function adds a flow limiter for this TokenManager. Can only be called by the operator.
* @param flowLimiter the address of the new flow limiter.
*/
function removeFlowLimiter(address flowLimiter) external onlyRole(uint8(Roles.OPERATOR)) {
if (flowLimiter == address(0)) revert ZeroAddress();

if (!hasRole(flowLimiter, uint8(Roles.FLOW_LIMITER))) revert NotFlowLimiter(flowLimiter);

_removeRole(flowLimiter, uint8(Roles.FLOW_LIMITER));
}

/**
* @notice This function sets the flow limit for this TokenManager. Can only be called by the flow limiters.
* @param flowLimit the maximum difference between the tokens flowing in and/or out at any given interval of time (6h)
*/
function setFlowLimit(uint256 flowLimit) external onlyOperator {
function setFlowLimit(uint256 flowLimit) external onlyRole(uint8(Roles.FLOW_LIMITER)) {
_setFlowLimit(flowLimit);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ contract TokenManagerLiquidityPool is TokenManager, NoReEntrancy, ITokenManagerL
* @dev Updates the address of the liquidity pool. Can only be called by the operator.
* @param newLiquidityPool The new address of the liquidity pool
*/
function setLiquidityPool(address newLiquidityPool) external onlyOperator {
function setLiquidityPool(address newLiquidityPool) external onlyRole(uint8(Roles.OPERATOR)) {
_setLiquidityPool(newLiquidityPool);
}

Expand Down
Loading

0 comments on commit ceade4a

Please sign in to comment.