53 lines
2.3 KiB
Solidity
53 lines
2.3 KiB
Solidity
// contracts/Implementation.sol
|
|
// SPDX-License-Identifier: Apache 2
|
|
|
|
pragma solidity ^0.8.0;
|
|
|
|
|
|
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
|
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
|
|
import "../../libraries/external/BytesLib.sol";
|
|
import "../../interfaces/IWormhole.sol";
|
|
|
|
interface ITokenBridge {
|
|
function completeTransferWithPayload(bytes memory encodedVm) external returns (bytes memory);
|
|
function wrappedAsset(uint16 tokenChainId, bytes32 tokenAddress) external view returns (address);
|
|
}
|
|
|
|
contract MockTokenBridgeIntegration {
|
|
using BytesLib for bytes;
|
|
using SafeERC20 for IERC20;
|
|
address tokenBridgeAddress;
|
|
function completeTransferAndSwap(bytes memory encodedVm) public {
|
|
// token bridge transfers are 133 bytes, our additional payload is 32 bytes = 165
|
|
// len - 165 + 33 = len - 132
|
|
bytes32 tokenAddress = encodedVm.toBytes32(encodedVm.length-132);
|
|
// len - 165 + 65 = len - 100
|
|
uint16 tokenChainId = encodedVm.toUint16(encodedVm.length-100);
|
|
address wrappedAddress = tokenBridge().wrappedAsset(tokenChainId, tokenAddress);
|
|
IERC20 transferToken = IERC20(wrappedAddress);
|
|
uint256 balanceBefore = transferToken.balanceOf(address(this));
|
|
bytes memory payload = tokenBridge().completeTransferWithPayload(encodedVm);
|
|
// make sure this vm is a payload 3
|
|
uint8 payloadType = payload.toUint8(0);
|
|
require(payloadType == 3, "invalid payload type");
|
|
bytes32 vmTokenAddress = payload.toBytes32(33);
|
|
require(tokenAddress == vmTokenAddress, 'Address parsed from VAA and payload do not match');
|
|
uint16 vmTokenChainId = payload.toUint16(65);
|
|
require(tokenChainId == vmTokenChainId, 'ChainId parsed from VAA and payload do not match');
|
|
uint256 balanceAfter = transferToken.balanceOf(address(this));
|
|
uint256 amount = balanceAfter - balanceBefore;
|
|
// additional field(s)
|
|
bytes32 receiver = payload.toBytes32(133);
|
|
address receiverAddress = address(uint160(uint256(receiver)));
|
|
transferToken.safeTransfer(receiverAddress, amount);
|
|
}
|
|
function tokenBridge() private view returns (ITokenBridge) {
|
|
return ITokenBridge(tokenBridgeAddress);
|
|
}
|
|
function setup(address _tokenBridge) public {
|
|
tokenBridgeAddress = _tokenBridge;
|
|
}
|
|
}
|