Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: inter-chain-token service events and errors [AXE-2064] #125

Merged
merged 29 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4f98632
refactor: contracts and interfaces for better error and event names, …
blockchainguyy Oct 12, 2023
c7e59a3
fix: tests for changes in errors and events
blockchainguyy Oct 12, 2023
cdd43d4
refactor: test/utils.js for expecting custom args with revert if prov…
blockchainguyy Oct 12, 2023
8fa38c0
refactor: update index.md for changes in errors and events
blockchainguyy Oct 12, 2023
5a47f53
chore: resolve conflicts with main
blockchainguyy Oct 16, 2023
f4ae099
chore: add operator address in event FlowLimitSet
blockchainguyy Oct 16, 2023
8c40a4d
chore: refactor error argument names
blockchainguyy Oct 16, 2023
df97235
Added roles, tests pending
Foivos Oct 17, 2023
8ea68ca
fix: tests
Oct 19, 2023
afdb98d
Merge remote-tracking branch 'origin/main' into feat/roles
Oct 19, 2023
fc0d72b
Added some tests and fixed constants
Foivos Oct 19, 2023
4b0586d
made lint happy
Foivos Oct 19, 2023
8c28d6d
Chnaged roles constants to enum to make slither happy
Foivos Oct 19, 2023
3ef1db2
Fixed tests
Foivos Oct 20, 2023
d2eeb46
Merge branch 'feat/roles' into refactor/errors-and-events
blockchainguyy Oct 25, 2023
53dc382
chore: also check error arguments in tests while reverting
blockchainguyy Oct 25, 2023
704fa25
chore: resolve pr comments for including tokenId in some errors
blockchainguyy Oct 25, 2023
6c4e38f
Added getter for distributor and opearator.
Foivos Oct 25, 2023
51a3ce4
made lint happy
Foivos Oct 25, 2023
68fcbdd
fixed a spelling error
Foivos Oct 25, 2023
d5ac83e
chore: add tokenManager address in deployment event and update tests
blockchainguyy Oct 25, 2023
6a27685
chore: add deployed token address in event
blockchainguyy Oct 26, 2023
3e55e98
chore: fix slither failing pipeline by adding comment
blockchainguyy Oct 26, 2023
d2db7e5
chore: resolve pr comments by adding params in erorrs and events, ad…
blockchainguyy Oct 26, 2023
fe2af9f
Merge remote-tracking branch 'origin/main' into feat/roles
Foivos Oct 27, 2023
479606e
Merge branch 'feat/roles' into refactor/errors-and-events
blockchainguyy Oct 31, 2023
7b5482b
fix: test after merging branch feat/roles
blockchainguyy Oct 31, 2023
5ab456c
Merge branch 'main' into refactor/errors-and-events
blockchainguyy Nov 1, 2023
3fcb1ad
fix: tests after resolving merge conflicts with main
blockchainguyy Nov 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions contracts/executable/InterchainTokenExecutable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pragma solidity ^0.8.0;
import { IInterchainTokenExecutable } from '../interfaces/IInterchainTokenExecutable.sol';

abstract contract InterchainTokenExecutable is IInterchainTokenExecutable {
error NotService();
error NotService(address caller);

address public immutable interchainTokenService;

Expand All @@ -16,7 +16,7 @@ abstract contract InterchainTokenExecutable is IInterchainTokenExecutable {
}

modifier onlyService() {
if (msg.sender != interchainTokenService) revert NotService();
if (msg.sender != interchainTokenService) revert NotService(msg.sender);
_;
}

Expand Down
52 changes: 35 additions & 17 deletions contracts/interchain-token-service/InterchainTokenService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ contract InterchainTokenService is
* @param tokenId the `tokenId` of the TokenManager trying to perform the call.
*/
modifier onlyTokenManager(bytes32 tokenId) {
if (msg.sender != getTokenManagerAddress(tokenId)) revert NotTokenManager();
address tokenManager = getTokenManagerAddress(tokenId);
if (msg.sender != tokenManager) revert NotTokenManager(msg.sender, tokenManager);

_;
blockchainguyy marked this conversation as resolved.
Show resolved Hide resolved
}

Expand Down Expand Up @@ -279,10 +281,14 @@ contract InterchainTokenService is
* @dev `gasValue` exists because this function can be part of a multicall involving multiple functions that could make remote contract calls.
*/
function deployRemoteCanonicalToken(bytes32 tokenId, string calldata destinationChain, uint256 gasValue) public payable notPaused {
address tokenAddress = getValidTokenManagerAddress(tokenId);
tokenAddress = ITokenManager(tokenAddress).tokenAddress();
address tokenAddress;
{
tokenAddress = getValidTokenManagerAddress(tokenId);
tokenAddress = ITokenManager(tokenAddress).tokenAddress();
bytes32 canonicalTokenId = getCanonicalTokenId(tokenAddress);

if (getCanonicalTokenId(tokenAddress) != tokenId) revert NotCanonicalTokenManager();
if (canonicalTokenId != tokenId) revert InvalidCanonicalTokenId(canonicalTokenId);
blockchainguyy marked this conversation as resolved.
Show resolved Hide resolved
}

(string memory tokenName, string memory tokenSymbol, uint8 tokenDecimals) = _validateToken(tokenAddress);
_deployRemoteStandardizedToken(tokenId, tokenName, tokenSymbol, tokenDecimals, '', '', 0, '', destinationChain, gasValue);
Expand Down Expand Up @@ -408,7 +414,7 @@ contract InterchainTokenService is
(uint256 selector, bytes32 tokenId, , uint256 amount) = abi.decode(payload, (uint256, bytes32, bytes, uint256));

if (selector != SELECTOR_RECEIVE_TOKEN && selector != SELECTOR_RECEIVE_TOKEN_WITH_DATA) {
revert InvalidExpressSelector();
revert InvalidExpressSelector(selector);
}

ITokenManager tokenManager = ITokenManager(getValidTokenManagerAddress(tokenId));
Expand All @@ -423,7 +429,7 @@ contract InterchainTokenService is
) external payable notPaused {
uint256 selector = abi.decode(payload, (uint256));
if (selector != SELECTOR_RECEIVE_TOKEN && selector != SELECTOR_RECEIVE_TOKEN_WITH_DATA) {
revert InvalidExpressSelector();
revert InvalidExpressSelector(selector);
}
if (gateway.isCommandExecuted(commandId)) revert AlreadyExecuted();

Expand Down Expand Up @@ -572,7 +578,8 @@ contract InterchainTokenService is
) internal pure returns (address implementation_) {
implementation_ = tokenManagerImplementations[uint256(tokenManagerType)];
if (implementation_ == address(0)) revert ZeroAddress();
if (ITokenManager(implementation_).implementationType() != uint256(tokenManagerType)) revert InvalidTokenManagerImplementation();
if (ITokenManager(implementation_).implementationType() != uint256(tokenManagerType))
revert InvalidTokenManagerImplementationType(implementation_);
}

/**
Expand Down Expand Up @@ -605,7 +612,7 @@ contract InterchainTokenService is
if (selector == SELECTOR_DEPLOY_TOKEN_MANAGER) return _processDeployTokenManagerPayload(payload);
if (selector == SELECTOR_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN) return _processDeployStandardizedTokenAndManagerPayload(payload);

revert SelectorUnknown();
revert SelectorUnknown(selector);
}

function contractCallWithTokenValue(
Expand Down Expand Up @@ -857,14 +864,19 @@ contract InterchainTokenService is
* @param params Additional parameters for the token manager deployment
*/
function _deployTokenManager(bytes32 tokenId, TokenManagerType tokenManagerType, bytes memory params) internal {
// slither-disable-next-line reentrancy-events
emit TokenManagerDeployed(tokenId, tokenManagerType, params);

// slither-disable-next-line controlled-delegatecall
(bool success, ) = tokenManagerDeployer.delegatecall(
(bool success, bytes memory returnData) = tokenManagerDeployer.delegatecall(
abi.encodeWithSelector(ITokenManagerDeployer.deployTokenManager.selector, tokenId, tokenManagerType, params)
);
if (!success) revert TokenManagerDeploymentFailed();
if (!success) revert TokenManagerDeploymentFailed(returnData);

address tokenManager;
assembly {
tokenManager := mload(add(returnData, 0x20))
}

// slither-disable-next-line reentrancy-events
blockchainguyy marked this conversation as resolved.
Show resolved Hide resolved
emit TokenManagerDeployed(tokenId, tokenManager, tokenManagerType, params);
}

/**
Expand Down Expand Up @@ -895,13 +907,11 @@ contract InterchainTokenService is
uint256 mintAmount,
address mintTo
) internal {
emit StandardizedTokenDeployed(tokenId, distributor, name, symbol, decimals, mintAmount, mintTo);

bytes32 salt = _getStandardizedTokenSalt(tokenId);
address tokenManagerAddress = getTokenManagerAddress(tokenId);

// slither-disable-next-line controlled-delegatecall
(bool success, ) = standardizedTokenDeployer.delegatecall(
(bool success, bytes memory returnData) = standardizedTokenDeployer.delegatecall(
abi.encodeWithSelector(
IStandardizedTokenDeployer.deployStandardizedToken.selector,
salt,
Expand All @@ -915,8 +925,16 @@ contract InterchainTokenService is
)
);
if (!success) {
revert StandardizedTokenDeploymentFailed();
revert StandardizedTokenDeploymentFailed(returnData);
}

address tokenAddress;
blockchainguyy marked this conversation as resolved.
Show resolved Hide resolved
assembly {
tokenAddress := mload(add(returnData, 0x20))
}

// slither-disable-next-line reentrancy-events
blockchainguyy marked this conversation as resolved.
Show resolved Hide resolved
emit StandardizedTokenDeployed(tokenId, tokenAddress, distributor, name, symbol, decimals, mintAmount, mintTo);
}

function _decodeMetadata(bytes memory metadata) internal pure returns (uint32 version, bytes memory data) {
Expand Down
4 changes: 2 additions & 2 deletions contracts/interfaces/IFlowLimit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
pragma solidity ^0.8.0;

interface IFlowLimit {
error FlowLimitExceeded();
error FlowLimitExceeded(uint256 limit, uint256 flowAmount);
blockchainguyy marked this conversation as resolved.
Show resolved Hide resolved

event FlowLimitSet(uint256 flowLimit);
event FlowLimitSet(bytes32 indexed tokenId, address operator, uint256 flowLimit);

/**
* @notice Returns the current flow limit
Expand Down
18 changes: 9 additions & 9 deletions contracts/interfaces/IInterchainTokenService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,20 @@ import { IRemoteAddressValidator } from './IRemoteAddressValidator.sol';
interface IInterchainTokenService is ITokenManagerType, IAxelarValuedExpressExecutable, IPausable, IMulticall, IContractIdentifier {
error ZeroAddress();
error LengthMismatch();
error InvalidTokenManagerImplementation();
error InvalidTokenManagerImplementationType(address implementation);
error NotRemoteService();
error TokenManagerDoesNotExist(bytes32 tokenId);
error NotTokenManager();
error NotTokenManager(address caller, address tokenManager);
error ExecuteWithInterchainTokenFailed(address contractAddress);
error InvalidCanonicalTokenId(bytes32 expectedCanonicalTokenId);
error ExpressExecuteWithInterchainTokenFailed(address contractAddress);
error NotCanonicalTokenManager();
error GatewayToken();
error TokenManagerDeploymentFailed();
error StandardizedTokenDeploymentFailed();
error DoesNotAcceptExpressExecute(address contractAddress);
error SelectorUnknown();
error TokenManagerDeploymentFailed(bytes error);
error StandardizedTokenDeploymentFailed(bytes error);
error SelectorUnknown(uint256 selector);
error InvalidMetadataVersion(uint32 version);
error ExecuteWithTokenNotSupported();
error InvalidExpressSelector();
error InvalidExpressSelector(uint256 selector);

event TokenSent(bytes32 indexed tokenId, string destinationChain, bytes destinationAddress, uint256 indexed amount);
event TokenSentWithData(
Expand Down Expand Up @@ -71,9 +70,10 @@ interface IInterchainTokenService is ITokenManagerType, IAxelarValuedExpressExec
string destinationChain,
uint256 indexed gasValue
);
event TokenManagerDeployed(bytes32 indexed tokenId, TokenManagerType indexed tokenManagerType, bytes params);
event TokenManagerDeployed(bytes32 indexed tokenId, address tokenManager, TokenManagerType indexed tokenManagerType, bytes params);
event StandardizedTokenDeployed(
bytes32 indexed tokenId,
address tokenAddress,
address indexed distributor,
string name,
string symbol,
Expand Down
3 changes: 2 additions & 1 deletion contracts/interfaces/IStandardizedTokenDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ interface IStandardizedTokenDeployer {
* @param decimals Decimals of the token
* @param mintAmount Amount of tokens to mint initially
* @param mintTo Address to mint initial tokens to
* @return tokenAddress Address of the deployed token
*/
function deployStandardizedToken(
bytes32 salt,
Expand All @@ -41,5 +42,5 @@ interface IStandardizedTokenDeployer {
uint8 decimals,
uint256 mintAmount,
address mintTo
) external payable;
) external payable returns (address tokenAddress);
}
4 changes: 2 additions & 2 deletions contracts/interfaces/ITokenManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import { IImplementation } from './IImplementation.sol';
*/
interface ITokenManager is ITokenManagerType, IOperatable, IFlowLimit, IImplementation {
error TokenLinkerZeroAddress();
error NotService();
error NotService(address caller);
error TakeTokenFailed();
error GiveTokenFailed();
error NotToken();
error NotToken(address caller);
error ZeroAddress();
error AlreadyFlowLimiter(address flowLimiter);
error NotFlowLimiter(address flowLimiter);
Expand Down
7 changes: 6 additions & 1 deletion contracts/interfaces/ITokenManagerDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ interface ITokenManagerDeployer {
* @param tokenId The unique identifier for the token
* @param implementationType Token manager implementation type
* @param params Additional parameters used in the setup of the token manager
* @return tokenManager Address of the deployed tokenManager
*/
function deployTokenManager(bytes32 tokenId, uint256 implementationType, bytes calldata params) external payable;
function deployTokenManager(
bytes32 tokenId,
uint256 implementationType,
bytes calldata params
) external payable returns (address tokenManager);
}
2 changes: 1 addition & 1 deletion contracts/interfaces/ITokenManagerProxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pragma solidity ^0.8.0;
*/
interface ITokenManagerProxy {
error ImplementationLookupFailed();
error SetupFailed();
error SetupFailed(bytes returnData);
error NativeTokenNotAccepted();

/**
Expand Down
4 changes: 2 additions & 2 deletions contracts/proxies/TokenManagerProxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ contract TokenManagerProxy is ITokenManagerProxy {
tokenId = tokenId_;
address impl = _getImplementation(IInterchainTokenService(interchainTokenServiceAddress_), implementationType_);

(bool success, ) = impl.delegatecall(abi.encodeWithSelector(TokenManagerProxy.setup.selector, params));
if (!success) revert SetupFailed();
(bool success, bytes memory returnData) = impl.delegatecall(abi.encodeWithSelector(TokenManagerProxy.setup.selector, params));
if (!success) revert SetupFailed(returnData);
}

/**
Expand Down
4 changes: 3 additions & 1 deletion contracts/test/utils/FlowLimitTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ pragma solidity ^0.8.0;
import { FlowLimit } from '../../utils/FlowLimit.sol';

contract FlowLimitTest is FlowLimit {
bytes32 public constant TOKEN_ID = 0x0;

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

function addFlowIn(uint256 flowInAmount) external {
Expand Down
9 changes: 6 additions & 3 deletions contracts/test/utils/FlowLimitTestLiveNetwork.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ 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'));
bytes32 public constant TOKEN_ID = 0x0;

uint256 internal constant EPOCH_TIME = 60;

Expand All @@ -22,7 +23,7 @@ contract FlowLimitTestLiveNetwork is IFlowLimit {
sstore(FLOW_LIMIT_SLOT, flowLimit)
}

emit FlowLimitSet(flowLimit);
emit FlowLimitSet(TOKEN_ID, msg.sender, flowLimit);
}

function _getFlowOutSlot(uint256 epoch) internal pure returns (uint256 slot) {
Expand Down Expand Up @@ -60,8 +61,10 @@ contract FlowLimitTestLiveNetwork is IFlowLimit {
flowToCompare := sload(slotToCompare)
}

if (flowToAdd + flowAmount > flowToCompare + flowLimit) revert FlowLimitExceeded();
if (flowAmount > flowLimit) revert FlowLimitExceeded();
uint256 maxFlowLimit = flowToCompare + flowLimit;
uint256 netFlowAmount = flowToAdd + flowAmount;
if (netFlowAmount > maxFlowLimit) revert FlowLimitExceeded(maxFlowLimit, netFlowAmount);
if (flowAmount > flowLimit) revert FlowLimitExceeded(flowLimit, flowAmount);

assembly {
sstore(slotToAdd, add(flowToAdd, flowAmount))
Expand Down
6 changes: 3 additions & 3 deletions contracts/token-manager/TokenManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ abstract contract TokenManager is ITokenManager, Operatable, FlowLimit, Implemen
* @dev A modifier that allows only the interchain token service to execute the function.
*/
modifier onlyService() {
if (msg.sender != address(interchainTokenService)) revert NotService();
if (msg.sender != address(interchainTokenService)) revert NotService(msg.sender);
_;
}

/**
* @dev A modifier that allows only the token to execute the function.
*/
modifier onlyToken() {
if (msg.sender != tokenAddress()) revert NotToken();
if (msg.sender != tokenAddress()) revert NotToken(msg.sender);
_;
}

Expand Down Expand Up @@ -224,7 +224,7 @@ abstract contract TokenManager is ITokenManager, Operatable, FlowLimit, Implemen
* @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 onlyRole(uint8(Roles.FLOW_LIMITER)) {
_setFlowLimit(flowLimit);
_setFlowLimit(flowLimit, tokenId());
}

/**
Expand Down
9 changes: 5 additions & 4 deletions contracts/utils/FlowLimit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ contract FlowLimit is IFlowLimit {
* @dev Internal function to set the flow limit
* @param flowLimit The value to set the flow limit to
*/
function _setFlowLimit(uint256 flowLimit) internal {
function _setFlowLimit(uint256 flowLimit, bytes32 tokenId) internal {
assembly {
sstore(FLOW_LIMIT_SLOT, flowLimit)
}

emit FlowLimitSet(flowLimit);
emit FlowLimitSet(tokenId, msg.sender, flowLimit);
}

/**
Expand Down Expand Up @@ -99,8 +99,9 @@ contract FlowLimit is IFlowLimit {
flowToCompare := sload(slotToCompare)
}

if (flowToAdd + flowAmount > flowToCompare + flowLimit) revert FlowLimitExceeded();
if (flowAmount > flowLimit) revert FlowLimitExceeded();
if (flowToAdd + flowAmount > flowToCompare + flowLimit)
revert FlowLimitExceeded((flowToCompare + flowLimit), flowToAdd + flowAmount);
blockchainguyy marked this conversation as resolved.
Show resolved Hide resolved
if (flowAmount > flowLimit) revert FlowLimitExceeded(flowLimit, flowAmount);

assembly {
sstore(slotToAdd, add(flowToAdd, flowAmount))
Expand Down
2 changes: 1 addition & 1 deletion contracts/utils/Multicall.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ contract Multicall is IMulticall {
(success, result) = address(this).delegatecall(data[i]);

if (!success) {
revert(string(result));
revert MulticallFailed(result);
}

results[i] = result;
Expand Down
5 changes: 3 additions & 2 deletions contracts/utils/StandardizedTokenDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ contract StandardizedTokenDeployer is IStandardizedTokenDeployer, Create3 {
* @param decimals Decimals of the token
* @param mintAmount Amount of tokens to mint initially
* @param mintTo Address to mint initial tokens to
* @return tokenAddress Address of the deployed token
*/
// slither-disable-next-line locked-ether
function deployStandardizedToken(
Expand All @@ -45,12 +46,12 @@ contract StandardizedTokenDeployer is IStandardizedTokenDeployer, Create3 {
uint8 decimals,
uint256 mintAmount,
address mintTo
) external payable {
) external payable returns (address tokenAddress) {
blockchainguyy marked this conversation as resolved.
Show resolved Hide resolved
bytes memory params = abi.encode(tokenManager, distributor, name, symbol, decimals, mintAmount, mintTo);
// slither-disable-next-line too-many-digits
bytes memory bytecode = bytes.concat(type(StandardizedTokenProxy).creationCode, abi.encode(implementationAddress, params));

address tokenAddress = _create3(bytecode, salt);
tokenAddress = _create3(bytecode, salt);
if (tokenAddress.code.length == 0) revert TokenDeploymentFailed();
}

Expand Down
Loading
Loading