Skip to content

Commit

Permalink
refactor: remove ERC20 dependency from BaseInterchainToken
Browse files Browse the repository at this point in the history
  • Loading branch information
milapsheth committed Dec 6, 2023
1 parent cf0e64b commit a1abfc2
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 13 deletions.
21 changes: 11 additions & 10 deletions contracts/interchain-token/BaseInterchainToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@ pragma solidity ^0.8.0;
import { IInterchainTokenStandard } from '../interfaces/IInterchainTokenStandard.sol';
import { IInterchainTokenService } from '../interfaces/IInterchainTokenService.sol';

import { ERC20 } from './ERC20.sol';

/**
* @title An example implementation of the IInterchainTokenStandard.
* @notice The implementation ERC20 can be done in any way, however this example assumes that an _approve internal function exists
* that can be used to create approvals, and that `allowance` is a mapping.
* @notice The is an abstract contract that needs to be extended with an ERC20 implementation. See `InterchainToken` for an example implementation.
*/
abstract contract BaseInterchainToken is IInterchainTokenStandard, ERC20 {
abstract contract BaseInterchainToken is IInterchainTokenStandard {
/**
* @notice Getter for the tokenId used for this token.
* @dev Needs to be overwritten.
Expand Down Expand Up @@ -48,6 +45,7 @@ abstract contract BaseInterchainToken is IInterchainTokenStandard, ERC20 {
_beforeInterchainTransfer(msg.sender, destinationChain, recipient, amount, metadata);

IInterchainTokenService service = IInterchainTokenService(interchainTokenService());

service.transmitInterchainTransfer{ value: msg.value }(interchainTokenId(), sender, destinationChain, recipient, amount, metadata);
}

Expand All @@ -68,15 +66,12 @@ abstract contract BaseInterchainToken is IInterchainTokenStandard, ERC20 {
uint256 amount,
bytes calldata metadata
) external payable {
uint256 _allowance = allowance[sender][msg.sender];

if (_allowance != UINT256_MAX) {
_approve(sender, msg.sender, _allowance - amount);
}
_spendAllowance(sender, msg.sender, amount);

_beforeInterchainTransfer(sender, destinationChain, recipient, amount, metadata);

IInterchainTokenService service = IInterchainTokenService(interchainTokenService());

service.transmitInterchainTransfer{ value: msg.value }(interchainTokenId(), sender, destinationChain, recipient, amount, metadata);
}

Expand All @@ -96,4 +91,10 @@ abstract contract BaseInterchainToken is IInterchainTokenStandard, ERC20 {
uint256 amount,
bytes calldata metadata
) internal virtual {}

/**
* @notice A method to be overwritten that will decrease the allowance of the `spender` from `sender` by `amount`.
* @dev Needs to be overwritten. This provides flexibility for the choice of ERC20 implementation used. Must revert if allowance is not sufficient.
*/
function _spendAllowance(address sender, address spender, uint256 amount) internal virtual;
}
15 changes: 14 additions & 1 deletion contracts/interchain-token/InterchainToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AddressBytes } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/
import { IInterchainToken } from '../interfaces/IInterchainToken.sol';

import { BaseInterchainToken } from './BaseInterchainToken.sol';
import { ERC20 } from './ERC20.sol';
import { ERC20Permit } from './ERC20Permit.sol';
import { Minter } from '../utils/Minter.sol';

Expand All @@ -15,7 +16,7 @@ import { Minter } from '../utils/Minter.sol';
* @notice This contract implements an interchain token which extends InterchainToken functionality.
* @dev This contract also inherits Minter and Implementation logic.
*/
contract InterchainToken is BaseInterchainToken, ERC20Permit, Minter, IInterchainToken {
contract InterchainToken is BaseInterchainToken, ERC20, ERC20Permit, Minter, IInterchainToken {
using AddressBytes for bytes;

string public name;
Expand Down Expand Up @@ -125,4 +126,16 @@ contract InterchainToken is BaseInterchainToken, ERC20Permit, Minter, IInterchai
function burn(address account, uint256 amount) external onlyRole(uint8(Roles.MINTER)) {
_burn(account, amount);
}

/**
* @notice A method to be overwritten that will decrease the allowance of the `spender` from `sender` by `amount`.
* @dev Needs to be overwritten. This provides flexibility for the choice of ERC20 implementation used. Must revert if allowance is not sufficient.
*/
function _spendAllowance(address sender, address spender, uint256 amount) internal override {
uint256 _allowance = allowance[sender][spender];

if (_allowance != UINT256_MAX) {
_approve(sender, spender, _allowance - amount);
}
}
}
11 changes: 10 additions & 1 deletion contracts/test/TestBaseInterchainToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
pragma solidity ^0.8.0;

import { BaseInterchainToken } from '../interchain-token/BaseInterchainToken.sol';
import { ERC20 } from '../interchain-token/ERC20.sol';
import { Minter } from '../utils/Minter.sol';
import { IERC20MintableBurnable } from '../interfaces/IERC20MintableBurnable.sol';

contract TestBaseInterchainToken is BaseInterchainToken, Minter, IERC20MintableBurnable {
contract TestBaseInterchainToken is BaseInterchainToken, Minter, ERC20, IERC20MintableBurnable {
address internal service;
bytes32 internal tokenId;
bool internal tokenManagerRequiresApproval_ = true;
Expand Down Expand Up @@ -52,6 +53,14 @@ contract TestBaseInterchainToken is BaseInterchainToken, Minter, IERC20MintableB
}
}

function _spendAllowance(address sender, address spender, uint256 amount) internal override {
uint256 _allowance = allowance[sender][spender];

if (_allowance != UINT256_MAX) {
_approve(sender, spender, _allowance - amount);
}
}

function setTokenManagerRequiresApproval(bool requiresApproval) public {
tokenManagerRequiresApproval_ = requiresApproval;
}
Expand Down
11 changes: 10 additions & 1 deletion contracts/test/TestFeeOnTransferToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
pragma solidity ^0.8.0;

import { BaseInterchainToken } from '../interchain-token/BaseInterchainToken.sol';
import { ERC20 } from '../interchain-token/ERC20.sol';
import { Minter } from '../utils/Minter.sol';
import { IERC20MintableBurnable } from '../interfaces/IERC20MintableBurnable.sol';

contract TestFeeOnTransferToken is BaseInterchainToken, Minter, IERC20MintableBurnable {
contract TestFeeOnTransferToken is BaseInterchainToken, ERC20, Minter, IERC20MintableBurnable {
address public immutable service;
bytes32 public tokenId;
bool internal tokenManagerRequiresApproval_ = true;
Expand Down Expand Up @@ -51,6 +52,14 @@ contract TestFeeOnTransferToken is BaseInterchainToken, Minter, IERC20MintableBu
}
}

function _spendAllowance(address sender, address spender, uint256 amount) internal override {
uint256 _allowance = allowance[sender][spender];

if (_allowance != UINT256_MAX) {
_approve(sender, spender, _allowance - amount);
}
}

function setTokenManagerRequiresApproval(bool requiresApproval) public {
tokenManagerRequiresApproval_ = requiresApproval;
}
Expand Down

0 comments on commit a1abfc2

Please sign in to comment.