Skip to content

Commit

Permalink
changed from tokenApprove to approveAndInterchainTransfer
Browse files Browse the repository at this point in the history
  • Loading branch information
Foivos committed Nov 7, 2023
1 parent 73b91cb commit 99bc5a0
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 14 deletions.
16 changes: 13 additions & 3 deletions contracts/InterchainTokenFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -221,14 +221,24 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M
}

/**
* @dev Allow any token to be approved to the token manager.
* TODO: Move this into a dedicated approve + transfer method to prevent unused approvals to be created that some tokens don't like.
* @dev This will still incur unwanted approvals for mint/burn token managers.
*/
function tokenApprove(bytes32 tokenId, uint256 amount) external payable {
function approveAndInterchainTransfer(
bytes32 tokenId,
string calldata destinationChain,
bytes calldata destinationAddress,
uint256 amount,
uint256 gasValue
) external payable {
if (bytes(destinationChain).length == 0) revert UnsetDestinationChainUnsupported();

address tokenAddress = service.validTokenAddress(tokenId);
IInterchainToken token = IInterchainToken(tokenAddress);
address tokenManager = service.tokenManagerAddress(tokenId);

token.safeCall(abi.encodeWithSelector(token.approve.selector, tokenManager, amount));

// slither-disable-next-line arbitrary-send-eth
service.interchainTransfer{ value: gasValue }(tokenId, destinationChain, destinationAddress, amount, new bytes(0));
}
}
9 changes: 8 additions & 1 deletion contracts/interfaces/IInterchainTokenFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface IInterchainTokenFactory {
error NotOperator(address operator);
error NonZeroMintAmount();
error ApproveFailed();
error UnsetDestinationChainUnsupported();

function chainNameHash() external view returns (bytes32);

Expand Down Expand Up @@ -58,5 +59,11 @@ interface IInterchainTokenFactory {

function tokenTransferFrom(bytes32 tokenId, uint256 amount) external payable;

function tokenApprove(bytes32 tokenId, uint256 amount) external payable;
function approveAndInterchainTransfer(
bytes32 tokenId,
string calldata destinationChain,
bytes calldata destinationAddress,
uint256 amount,
uint256 gasValue
) external payable;
}
27 changes: 23 additions & 4 deletions test/InterchainTokenFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ describe('InterchainTokenFactory', () => {

it('Should approve some tokens from the factory to the token manager', async () => {
const amount = 123456;
const destinationAddress = '0x57689403';
const gasValue = 45960;

await deployToken();

Expand All @@ -120,9 +122,21 @@ describe('InterchainTokenFactory', () => {

tokenManagerAddress = await service.validTokenManagerAddress(tokenId);

await expect(tokenFactory.tokenApprove(tokenId, amount))
await expect(token.transfer(tokenFactory.address, amount))
.to.emit(token, 'Transfer')
.withArgs(wallet.address, tokenFactory.address, amount);

await expect(
tokenFactory.approveAndInterchainTransfer(tokenId, destinationChain, destinationAddress, amount, gasValue, {
value: gasValue,
}),
)
.to.emit(token, 'Approval')
.withArgs(tokenFactory.address, tokenManagerAddress, amount);
.withArgs(tokenFactory.address, tokenManagerAddress, amount)
.and.to.emit(token, 'Transfer')
.withArgs(tokenFactory.address, tokenManagerAddress, amount)
.and.to.emit(service, 'InterchainTransfer')
.withArgs(tokenId, destinationChain, destinationAddress, amount);
});

it('Should transfer some tokens through the factory as the deployer', async () => {
Expand All @@ -145,9 +159,14 @@ describe('InterchainTokenFactory', () => {
const txs = [];

txs.push(await tokenFactory.populateTransaction.tokenTransferFrom(tokenId, amount));
txs.push(await tokenFactory.populateTransaction.tokenApprove(tokenId, amount));
txs.push(
await tokenFactory.populateTransaction.interchainTransfer(tokenId, destinationChain, destinationAddress, amount, gasValue),
await tokenFactory.populateTransaction.approveAndInterchainTransfer(
tokenId,
destinationChain,
destinationAddress,
amount,
gasValue,
),
);

await expect(
Expand Down
12 changes: 6 additions & 6 deletions test/TokenServiceFullFlow.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,9 @@ describe('Interchain Token Service Full Flow', () => {
tx = await factory.populateTransaction.tokenTransferFrom(tokenId, totalMint);
calls.push(tx.data);

// Approve total mint amount from the factory to the token manager contract
tx = await factory.populateTransaction.tokenApprove(tokenId, totalMint);
calls.push(tx.data);

// Transfer tokens from factory contract to the user on remote chains.
for (const i in otherChains) {
tx = await factory.populateTransaction.interchainTransfer(
tx = await factory.populateTransaction.approveAndInterchainTransfer(
tokenId,
otherChains[i],
wallet.address,
Expand Down Expand Up @@ -129,7 +125,11 @@ describe('Interchain Token Service Full Flow', () => {
.and.to.emit(token, 'Transfer')
.withArgs(wallet.address, factory.address, totalMint)
.and.to.emit(token, 'Approval')
.withArgs(factory.address, expectedTokenManagerAddress, totalMint)
.withArgs(factory.address, expectedTokenManagerAddress, mintAmount)
.and.to.emit(token, 'Transfer')
.withArgs(factory.address, expectedTokenManagerAddress, mintAmount)
.and.to.emit(token, 'Approval')
.withArgs(factory.address, expectedTokenManagerAddress, mintAmount)
.and.to.emit(token, 'Transfer')
.withArgs(factory.address, expectedTokenManagerAddress, mintAmount);
});
Expand Down

0 comments on commit 99bc5a0

Please sign in to comment.