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

feat: custom token registrars #116

Merged
merged 59 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
e9c1939
Added a canonical token registrar.
Foivos Oct 2, 2023
10e4503
wrote some canonical token registrar tests
Foivos Oct 2, 2023
2866ecf
made the standardized token registrar
Foivos Oct 2, 2023
1127093
Wrote some basic tests
Foivos Oct 3, 2023
943de1f
Merge remote-tracking branch 'origin/main' into feat/custom-token-reg…
Foivos Oct 3, 2023
09b66bb
lint and fix a merge bug
Foivos Oct 3, 2023
f4ef75b
feat: bump to latest gmp-sdk and cgp
milapsheth Oct 9, 2023
4569336
Merge branch 'axe-2034' into feat/custom-token-registars
milapsheth Oct 9, 2023
14fecc4
rebase over dep bump
milapsheth Oct 9, 2023
8682513
Merge branch 'main' into feat/custom-token-registars
milapsheth Oct 12, 2023
1bd5f9b
clean lock file
milapsheth Oct 12, 2023
3391cd8
Merge branch 'main' into feat/custom-token-registars
milapsheth Oct 12, 2023
f82b23c
Merge branch 'main' into feat/custom-token-registars
milapsheth Oct 12, 2023
f0a7e29
slither checks
milapsheth Oct 12, 2023
04972f9
Merge branch 'main' into feat/custom-token-registars
milapsheth Oct 12, 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
1566fec
Merge branch 'main' into feat/custom-token-registars
milapsheth Oct 23, 2023
ed4be65
querrying chain name from the remoteAddressValidator for the registrars
Foivos Oct 25, 2023
4ec3612
Merge remote-tracking branch 'origin/feat/custom-token-registars' int…
Foivos Oct 25, 2023
844bfb6
Merge remote-tracking branch 'origin/feat/roles' into feat/custom-tok…
Foivos Oct 25, 2023
a8db922
stash to add more utils to roles.
Foivos 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
7b69d55
Merge branch 'feat/roles' into feat/custom-token-registars
Foivos Oct 25, 2023
7815108
Fixed tests and interfaces
Foivos Oct 25, 2023
de5bcda
Removed a lot of unused imports and made routers upgradable.
Foivos Oct 27, 2023
fe2af9f
Merge remote-tracking branch 'origin/main' into feat/roles
Foivos Oct 27, 2023
6147bf3
Merge remote-tracking branch 'origin/main' into feat/custom-token-reg…
Foivos Oct 30, 2023
09fa22d
Merge branch 'feat/roles' into feat/custom-token-registars
Foivos Oct 30, 2023
551f67e
Addressed changes
Foivos Oct 31, 2023
a6216f0
update for the new roles functions
Foivos Oct 31, 2023
992ba96
Merge branch 'feat/roles' into feat/custom-token-registars
Foivos Oct 31, 2023
05c1855
allow for mintAmount for standardized tokens
Foivos Oct 31, 2023
a593d69
Merge remote-tracking branch 'origin/main' into feat/roles
Foivos Oct 31, 2023
2831316
update sdk
Foivos Oct 31, 2023
394dca9
Merge branch 'main' into feat/roles
Foivos Oct 31, 2023
c555815
updage to newest sdk
Foivos Oct 31, 2023
fc791d1
made lint happy
Foivos Oct 31, 2023
6cc49c0
Merge branch 'feat/roles' into feat/custom-token-registars
Foivos Oct 31, 2023
b8ab648
added some changes
Foivos Oct 31, 2023
a8aac7d
Merge remote-tracking branch 'origin/main' into feat/custom-token-reg…
Foivos Oct 31, 2023
7d4d5bd
Added some utilities
Foivos Oct 31, 2023
ca65004
made lint happy
Foivos Oct 31, 2023
f190a59
Merge branch 'main' into feat/custom-token-registars
milapsheth Oct 31, 2023
9ac0cf7
fix test
milapsheth Oct 31, 2023
3b76ac1
build warnings
milapsheth Oct 31, 2023
44dc8fc
revert fix
milapsheth Nov 1, 2023
83353a6
fix create3 deployer reference
milapsheth Nov 1, 2023
e692dbc
fix test
milapsheth Nov 1, 2023
f2d76c2
slither warnings
milapsheth Nov 1, 2023
0f78048
switch proxies
milapsheth Nov 1, 2023
f7f4b47
fix import
milapsheth 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
3 changes: 2 additions & 1 deletion .solhint.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"no-inline-assembly": "off",
"no-empty-blocks": "off",
"avoid-low-level-calls": "off",
"not-rely-on-time": "off"
"not-rely-on-time": "off",
"immutable-vars-naming": "off"
}
}
13 changes: 10 additions & 3 deletions contracts/interchain-token-service/InterchainTokenService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { IRemoteAddressValidator } from '../interfaces/IRemoteAddressValidator.s
import { IInterchainTokenExecutable } from '../interfaces/IInterchainTokenExecutable.sol';
import { IInterchainTokenExpressExecutable } from '../interfaces/IInterchainTokenExpressExecutable.sol';
import { ITokenManager } from '../interfaces/ITokenManager.sol';
import { ITokenManagerProxy } from '../interfaces/ITokenManagerProxy.sol';
import { IERC20Named } from '../interfaces/IERC20Named.sol';

import { AddressBytesUtils } from '../libraries/AddressBytesUtils.sol';
Expand Down Expand Up @@ -475,13 +474,21 @@ contract InterchainTokenService is
}
}

/**
* @notice Transfer a token interchain.
* @param tokenId the tokenId for the token link.
* @param destinationChain the name of the chain to send the token to.
* @param destinationAddress the recipient of the interchain transfer.
* @param amount the amount of token to give.
* @param metadata the data to be passed to the destination. If provided with a bytes4(0) prefix, it'll execute the destination contract.
*/
function interchainTransfer(
bytes32 tokenId,
string calldata destinationChain,
bytes calldata destinationAddress,
uint256 amount,
bytes calldata metadata
) external notPaused {
) external payable notPaused {
ITokenManager tokenManager = ITokenManager(getTokenManagerAddress(tokenId));
amount = tokenManager.takeToken(msg.sender, amount);
_transmitSendToken(tokenId, msg.sender, destinationChain, destinationAddress, amount, metadata);
Expand All @@ -493,7 +500,7 @@ contract InterchainTokenService is
bytes calldata destinationAddress,
uint256 amount,
bytes calldata data
) external notPaused {
) external payable notPaused {
ITokenManager tokenManager = ITokenManager(getTokenManagerAddress(tokenId));
amount = tokenManager.takeToken(msg.sender, amount);
uint32 prefix = 0;
Expand Down
18 changes: 18 additions & 0 deletions contracts/interfaces/ICanonicalTokenRegistrar.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface ICanonicalTokenRegistrar {
error ZeroAddress();
error ApproveFailed();

function chainNameHash() external view returns (bytes32);

function getCanonicalTokenSalt(address tokenAddress) external view returns (bytes32 salt);

function getCanonicalTokenId(address tokenAddress) external view returns (bytes32 tokenId);
Comment on lines +11 to +13
Copy link
Member

@milapsheth milapsheth Oct 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove get prefix from registrar contracts as well (along with ITS)


function registerCanonicalToken(address tokenAddress) external payable returns (bytes32 tokenId);

function deployAndRegisterRemoteCanonicalToken(bytes32 salt, string calldata destinationChain, uint256 gasValue) external payable;
}
4 changes: 3 additions & 1 deletion contracts/interfaces/IDistributable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

pragma solidity ^0.8.0;

interface IDistributable {
import { IRolesBase } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IRolesBase.sol';

interface IDistributable is IRolesBase {
/**
* @notice Change the distributor of the contract
* @dev Can only be called by the current distributor
Expand Down
11 changes: 9 additions & 2 deletions contracts/interfaces/IInterchainTokenService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { IContractIdentifier } from '@axelar-network/axelar-gmp-sdk-solidity/con
import { ITokenManagerType } from './ITokenManagerType.sol';
import { IPausable } from './IPausable.sol';
import { IMulticall } from './IMulticall.sol';
import { IRemoteAddressValidator } from './IRemoteAddressValidator.sol';

interface IInterchainTokenService is ITokenManagerType, IAxelarValuedExpressExecutable, IPausable, IMulticall, IContractIdentifier {
error ZeroAddress();
Expand Down Expand Up @@ -82,6 +83,12 @@ interface IInterchainTokenService is ITokenManagerType, IAxelarValuedExpressExec
);
event CustomTokenIdClaimed(bytes32 indexed tokenId, address indexed deployer, bytes32 indexed salt);

/**
* @notice Returns the address of the token manager deployer contract.
* @return remoteAddressValidator_ The remoteAddressValidator.
*/
function remoteAddressValidator() external view returns (IRemoteAddressValidator remoteAddressValidator_);

/**
* @notice Returns the address of the token manager deployer contract.
* @return tokenManagerDeployerAddress The address of the token manager deployer contract.
Expand Down Expand Up @@ -238,15 +245,15 @@ interface IInterchainTokenService is ITokenManagerType, IAxelarValuedExpressExec
bytes calldata destinationAddress,
uint256 amount,
bytes calldata metadata
) external;
) external payable;

function sendTokenWithData(
bytes32 tokenId,
string calldata destinationChain,
bytes calldata destinationAddress,
uint256 amount,
bytes calldata data
) external;
) external payable;

/**
* @notice Initiates an interchain token transfer. Only callable by TokenManagers
Expand Down
4 changes: 3 additions & 1 deletion contracts/interfaces/IOperatable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

pragma solidity ^0.8.0;

interface IOperatable {
import { IRolesBase } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IRolesBase.sol';

interface IOperatable is IRolesBase {
/**
* @notice Change the operator of the contract
* @dev Can only be called by the current operator
Expand Down
20 changes: 17 additions & 3 deletions contracts/interfaces/IStandardizedToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,34 @@

pragma solidity ^0.8.0;

import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol';
import { IContractIdentifier } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IContractIdentifier.sol';

import { IImplementation } from './IImplementation.sol';
import { IInterchainToken } from './IInterchainToken.sol';
import { IDistributable } from './IDistributable.sol';
import { IERC20MintableBurnable } from './IERC20MintableBurnable.sol';
import { ITokenManager } from './ITokenManager.sol';
import { IERC20Named } from './IERC20Named.sol';

/**
* @title StandardizedToken
* @notice This contract implements a standardized token which extends InterchainToken functionality.
* This contract also inherits Distributable and Implementation logic.
*/
interface IStandardizedToken is IImplementation, IInterchainToken, IDistributable, IERC20MintableBurnable, IERC20, IContractIdentifier {
interface IStandardizedToken is IInterchainToken, IDistributable, IERC20MintableBurnable, IERC20Named, IContractIdentifier {
error TokenManagerAddressZero();
error TokenNameEmpty();

/**
* @notice Called by the proxy to setup itself.
* @dev This should be hidden by the proxy.
* @param params the data to be used for the initialization.
*/
function setup(bytes calldata params) external;

/**
* @notice Getter for the tokenManager used for this token.
* @dev Needs to be overwitten.
* @return tokenManager_ the TokenManager called to facilitate cross chain transfers.
*/
function tokenManager() external view returns (ITokenManager tokenManager_);
}
2 changes: 0 additions & 2 deletions contracts/interfaces/IStandardizedTokenDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

pragma solidity ^0.8.0;

import { Create3Deployer } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/deploy/Create3Deployer.sol';

/**
* @title IStandardizedTokenDeployer
* @notice This contract is used to deploy new instances of the StandardizedTokenProxy contract.
Expand Down
36 changes: 36 additions & 0 deletions contracts/interfaces/IStandardizedTokenRegistrar.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IStandardizedTokenRegistrar {
error ZeroAddress();
error NotDistributor(address distributor);
error NotOperator(address operator);
error NonZeroMintAmount();

function chainNameHash() external view returns (bytes32);

function getStandardizedTokenSalt(address deployer, bytes32 salt) external view returns (bytes32);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same get comment


function getStandardizedTokenId(address deployer, bytes32 salt) external view returns (bytes32 tokenId);

function getStandardizedTokenAddress(address deployer, bytes32 salt) external view returns (address tokenAddress);

function deployStandardizedToken(
bytes32 salt,
string calldata name,
string calldata symbol,
uint8 decimals,
uint256 mintAmount,
address distributor
) external payable;

function deployRemoteStandarizedToken(
bytes32 salt,
address additionalDistributor,
address optionalOperator,
uint256 mintAmount,
string memory destinationChain,
uint256 gasValue
) external payable;
}
2 changes: 0 additions & 2 deletions contracts/interfaces/ITokenManagerDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

pragma solidity ^0.8.0;

import { Create3Deployer } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/deploy/Create3Deployer.sol';

/**
* @title ITokenManagerDeployer
* @notice This contract is used to deploy new instances of the TokenManagerProxy contract.
Expand Down
28 changes: 28 additions & 0 deletions contracts/proxies/CanonicalTokenRegistrarProxy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { Proxy } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Proxy.sol';

/**
* @title CanonicalTokenRegistrarProxy
* @dev Proxy contract for interchain token service contracts. Inherits from the Proxy contract.
*/
contract CanonicalTokenRegistrarProxy is Proxy {
bytes32 private constant CONTRACT_ID = keccak256('canonical-token-registrar');

/**
* @dev Constructs the InterchainTokenServiceProxy contract.
* @param implementationAddress Address of the interchain token service implementation
* @param owner Address of the owner of the proxy
*/
constructor(address implementationAddress, address owner) Proxy(implementationAddress, owner, '') {}

/**
* @dev Override for the 'contractId' function in FinalProxy. Returns a unique identifier for this contract.
* @return bytes32 identifier for this contract
*/
function contractId() internal pure override returns (bytes32) {
return CONTRACT_ID;
}
}
28 changes: 28 additions & 0 deletions contracts/proxies/StandardizedTokenRegistrarProxy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { Proxy } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Proxy.sol';

/**
* @title StandardizedTokenRegistrarProxy
* @dev Proxy contract for interchain token service contracts. Inherits from the Proxy contract.
*/
contract StandardizedTokenRegistrarProxy is Proxy {
bytes32 private constant CONTRACT_ID = keccak256('standardized-token-registrar');

/**
* @dev Constructs the InterchainTokenServiceProxy contract.
* @param implementationAddress Address of the interchain token service implementation
* @param owner Address of the owner of the proxy
*/
constructor(address implementationAddress, address owner) Proxy(implementationAddress, owner, '') {}

/**
* @dev Override for the 'contractId' function in FinalProxy. Returns a unique identifier for this contract.
* @return bytes32 identifier for this contract
*/
function contractId() internal pure override returns (bytes32) {
return CONTRACT_ID;
}
}
13 changes: 8 additions & 5 deletions contracts/test/HardCodedConstantsTest.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: MIT

// solhint-disable-next-line one-contract-per-file
pragma solidity ^0.8.0;

import { TokenManagerLiquidityPool } from '../token-manager/implementations/TokenManagerLiquidityPool.sol';
Expand All @@ -9,12 +10,14 @@ import { NoReEntrancy } from '../utils/NoReEntrancy.sol';
import { Operatable } from '../utils/Operatable.sol';
import { Pausable } from '../utils/Pausable.sol';

error Invalid();

contract TestTokenManager is TokenManagerLiquidityPool {
string public constant NAME = 'TestTokenManager';

constructor(address interchainTokenService_) TokenManagerLiquidityPool(interchainTokenService_) {
require(TOKEN_ADDRESS_SLOT == uint256(keccak256('token-address')) - 1, 'invalid constant');
require(LIQUIDITY_POOL_SLOT == uint256(keccak256('liquidity-pool-slot')) - 1, 'invalid constant');
if (TOKEN_ADDRESS_SLOT != uint256(keccak256('token-address')) - 1) revert Invalid();
if (LIQUIDITY_POOL_SLOT != uint256(keccak256('liquidity-pool-slot')) - 1) revert Invalid();
}
}

Expand All @@ -28,15 +31,15 @@ contract TestFlowLimit is FlowLimit {
string public constant NAME = 'TestFlowLimit';

constructor() {
require(FLOW_LIMIT_SLOT == uint256(keccak256('flow-limit')) - 1, 'invalid constant');
if (FLOW_LIMIT_SLOT != uint256(keccak256('flow-limit')) - 1) revert Invalid();
}
}

contract TestNoReEntrancy is NoReEntrancy {
string public constant NAME = 'TestNoReEntrancy';

constructor() {
require(ENTERED_SLOT == uint256(keccak256('entered')) - 1, 'invalid constant');
if (ENTERED_SLOT != uint256(keccak256('entered')) - 1) revert Invalid();
}
}

Expand All @@ -50,6 +53,6 @@ contract TestPausable is Pausable {
string public constant NAME = 'TestPausable';

constructor() {
require(PAUSE_SLOT == uint256(keccak256('paused')) - 1, 'invalid constant');
if (PAUSE_SLOT != uint256(keccak256('paused')) - 1) revert Invalid();
}
}
1 change: 0 additions & 1 deletion contracts/test/InterchainExecutableTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
pragma solidity ^0.8.0;

import { InterchainTokenExpressExecutable } from '../executable/InterchainTokenExpressExecutable.sol';
import { IInterchainTokenService } from '../interfaces/IInterchainTokenService.sol';
import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol';

contract InterchainExecutableTest is InterchainTokenExpressExecutable {
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/utils/MulticallTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ contract MulticallTest is Multicall {
}

function function3() external pure {
// solhint-disable-next-line reason-string
// solhint-disable-next-line reason-string,custom-errors
revert();
}

Expand Down
6 changes: 3 additions & 3 deletions contracts/token-implementations/StandardizedToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

pragma solidity ^0.8.0;

import { IImplementation } from '../interfaces/IImplementation.sol';
import { IStandardizedToken } from '../interfaces/IStandardizedToken.sol';
import { ITokenManager } from '../interfaces/ITokenManager.sol';
import { IInterchainToken } from '../interfaces/IInterchainToken.sol';

import { InterchainToken } from '../interchain-token/InterchainToken.sol';
import { ERC20Permit } from '../token-implementations/ERC20Permit.sol';
Expand Down Expand Up @@ -38,7 +38,7 @@ contract StandardizedToken is InterchainToken, ERC20Permit, Implementation, Dist
* @notice Returns the token manager for this token
* @return ITokenManager The token manager contract
*/
function tokenManager() public view override(InterchainToken, IInterchainToken) returns (ITokenManager) {
function tokenManager() public view override(InterchainToken, IStandardizedToken) returns (ITokenManager) {
return ITokenManager(tokenManager_);
}

Expand All @@ -47,7 +47,7 @@ contract StandardizedToken is InterchainToken, ERC20Permit, Implementation, Dist
* @param params The setup parameters in bytes
* The setup params include tokenManager, distributor, tokenName, symbol, decimals, mintAmount and mintTo
*/
function setup(bytes calldata params) external override onlyProxy {
function setup(bytes calldata params) external override(IImplementation, IStandardizedToken) onlyProxy {
{
address distributor_;
address tokenManagerAddress;
Expand Down
1 change: 0 additions & 1 deletion contracts/token-manager/TokenManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ pragma solidity ^0.8.0;

import { ITokenManager } from '../interfaces/ITokenManager.sol';
import { IInterchainTokenService } from '../interfaces/IInterchainTokenService.sol';
import { ITokenManagerProxy } from '../interfaces/ITokenManagerProxy.sol';

import { Operatable } from '../utils/Operatable.sol';
import { FlowLimit } from '../utils/FlowLimit.sol';
Expand Down
Loading
Loading