evm: add token and nft bridge interface (#1710)
* Add token and nft bridge interface * Add wormhole method to nft and bridge interface * ethereum: add test to ensure interface match * Add all public methods to interfaces Co-authored-by: gator-boi <gator-boi@users.noreply.github.com> Co-authored-by: Evan Gray <battledingo@gmail.com>
This commit is contained in:
parent
ddb2afdf36
commit
bac99e912f
|
@ -48,6 +48,9 @@ test-upgrade: build .env node_modules
|
||||||
|
|
||||||
.PHONY:
|
.PHONY:
|
||||||
test-forge: dependencies
|
test-forge: dependencies
|
||||||
|
./compare-method-identifiers.sh contracts/Implementation.sol:Implementation contracts/interfaces/IWormhole.sol:IWormhole
|
||||||
|
./compare-method-identifiers.sh contracts/bridge/BridgeImplementation.sol:BridgeImplementation contracts/bridge/interfaces/ITokenBridge.sol:ITokenBridge
|
||||||
|
./compare-method-identifiers.sh contracts/nft/NFTBridgeImplementation.sol:NFTBridgeImplementation contracts/nft/interfaces/INFTBridge.sol:INFTBridge
|
||||||
forge test
|
forge test
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/bash
|
||||||
|
TMP=$(mktemp -d)
|
||||||
|
f1="$TMP/$1.interface"
|
||||||
|
f2="$TMP/$2.interface"
|
||||||
|
mkdir -p $(dirname "$f1")
|
||||||
|
mkdir -p $(dirname "$f2")
|
||||||
|
function clean_up () {
|
||||||
|
ARG=$?
|
||||||
|
rm -rf "$TMP"
|
||||||
|
exit $ARG
|
||||||
|
}
|
||||||
|
trap clean_up SIGINT SIGTERM EXIT
|
||||||
|
forge inspect $1 mi > "$f1"
|
||||||
|
forge inspect $2 mi > "$f2"
|
||||||
|
git diff --no-index "$f1" "$f2" --exit-code && echo "✅ Method interfaces are identical" || (echo "❌ Method interfaces are different" >&2 && exit 1)
|
|
@ -6,6 +6,7 @@ pragma solidity ^0.8.0;
|
||||||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||||
|
|
||||||
import "../interfaces/IWormhole.sol";
|
import "../interfaces/IWormhole.sol";
|
||||||
|
import "./interfaces/IWETH.sol";
|
||||||
|
|
||||||
import "./BridgeState.sol";
|
import "./BridgeState.sol";
|
||||||
|
|
||||||
|
@ -74,9 +75,3 @@ contract BridgeGetters is BridgeState {
|
||||||
return _state.provider.finality;
|
return _state.provider.finality;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IWETH is IERC20 {
|
|
||||||
function deposit() external payable;
|
|
||||||
|
|
||||||
function withdraw(uint amount) external;
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
// contracts/Bridge.sol
|
||||||
|
// SPDX-License-Identifier: Apache 2
|
||||||
|
|
||||||
|
pragma solidity ^0.8.0;
|
||||||
|
|
||||||
|
import "./IWETH.sol";
|
||||||
|
import "../../interfaces/IWormhole.sol";
|
||||||
|
|
||||||
|
interface ITokenBridge {
|
||||||
|
struct Transfer {
|
||||||
|
uint8 payloadID;
|
||||||
|
uint256 amount;
|
||||||
|
bytes32 tokenAddress;
|
||||||
|
uint16 tokenChain;
|
||||||
|
bytes32 to;
|
||||||
|
uint16 toChain;
|
||||||
|
uint256 fee;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TransferWithPayload {
|
||||||
|
uint8 payloadID;
|
||||||
|
uint256 amount;
|
||||||
|
bytes32 tokenAddress;
|
||||||
|
uint16 tokenChain;
|
||||||
|
bytes32 to;
|
||||||
|
uint16 toChain;
|
||||||
|
bytes32 fromAddress;
|
||||||
|
bytes payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AssetMeta {
|
||||||
|
uint8 payloadID;
|
||||||
|
bytes32 tokenAddress;
|
||||||
|
uint16 tokenChain;
|
||||||
|
uint8 decimals;
|
||||||
|
bytes32 symbol;
|
||||||
|
bytes32 name;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RegisterChain {
|
||||||
|
bytes32 module;
|
||||||
|
uint8 action;
|
||||||
|
uint16 chainId;
|
||||||
|
|
||||||
|
uint16 emitterChainID;
|
||||||
|
bytes32 emitterAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UpgradeContract {
|
||||||
|
bytes32 module;
|
||||||
|
uint8 action;
|
||||||
|
uint16 chainId;
|
||||||
|
|
||||||
|
bytes32 newContract;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RecoverChainId {
|
||||||
|
bytes32 module;
|
||||||
|
uint8 action;
|
||||||
|
|
||||||
|
uint256 evmChainId;
|
||||||
|
uint16 newChainId;
|
||||||
|
}
|
||||||
|
|
||||||
|
event ContractUpgraded(address indexed oldContract, address indexed newContract);
|
||||||
|
|
||||||
|
function _parseTransferCommon(bytes memory encoded) external pure returns (Transfer memory transfer);
|
||||||
|
|
||||||
|
function attestToken(address tokenAddress, uint32 nonce) external payable returns (uint64 sequence);
|
||||||
|
|
||||||
|
function wrapAndTransferETH(uint16 recipientChain, bytes32 recipient, uint256 arbiterFee, uint32 nonce) external payable returns (uint64 sequence);
|
||||||
|
|
||||||
|
function wrapAndTransferETHWithPayload(uint16 recipientChain, bytes32 recipient, uint32 nonce, bytes memory payload) external payable returns (uint64 sequence);
|
||||||
|
|
||||||
|
function transferTokens(address token, uint256 amount, uint16 recipientChain, bytes32 recipient, uint256 arbiterFee, uint32 nonce) external payable returns (uint64 sequence);
|
||||||
|
|
||||||
|
function transferTokensWithPayload(address token, uint256 amount, uint16 recipientChain, bytes32 recipient, uint32 nonce, bytes memory payload) external payable returns (uint64 sequence);
|
||||||
|
|
||||||
|
function updateWrapped(bytes memory encodedVm) external returns (address token);
|
||||||
|
|
||||||
|
function createWrapped(bytes memory encodedVm) external returns (address token);
|
||||||
|
|
||||||
|
function completeTransferWithPayload(bytes memory encodedVm) external returns (bytes memory);
|
||||||
|
|
||||||
|
function completeTransferAndUnwrapETHWithPayload(bytes memory encodedVm) external returns (bytes memory);
|
||||||
|
|
||||||
|
function completeTransfer(bytes memory encodedVm) external;
|
||||||
|
|
||||||
|
function completeTransferAndUnwrapETH(bytes memory encodedVm) external;
|
||||||
|
|
||||||
|
function encodeAssetMeta(AssetMeta memory meta) external pure returns (bytes memory encoded);
|
||||||
|
|
||||||
|
function encodeTransfer(Transfer memory transfer) external pure returns (bytes memory encoded);
|
||||||
|
|
||||||
|
function encodeTransferWithPayload(TransferWithPayload memory transfer) external pure returns (bytes memory encoded);
|
||||||
|
|
||||||
|
function parsePayloadID(bytes memory encoded) external pure returns (uint8 payloadID);
|
||||||
|
|
||||||
|
function parseAssetMeta(bytes memory encoded) external pure returns (AssetMeta memory meta);
|
||||||
|
|
||||||
|
function parseTransfer(bytes memory encoded) external pure returns (Transfer memory transfer);
|
||||||
|
|
||||||
|
function parseTransferWithPayload(bytes memory encoded) external pure returns (TransferWithPayload memory transfer);
|
||||||
|
|
||||||
|
function governanceActionIsConsumed(bytes32 hash) external view returns (bool);
|
||||||
|
|
||||||
|
function isInitialized(address impl) external view returns (bool);
|
||||||
|
|
||||||
|
function isTransferCompleted(bytes32 hash) external view returns (bool);
|
||||||
|
|
||||||
|
function wormhole() external view returns (IWormhole);
|
||||||
|
|
||||||
|
function chainId() external view returns (uint16);
|
||||||
|
|
||||||
|
function evmChainId() external view returns (uint256);
|
||||||
|
|
||||||
|
function isFork() external view returns (bool);
|
||||||
|
|
||||||
|
function governanceChainId() external view returns (uint16);
|
||||||
|
|
||||||
|
function governanceContract() external view returns (bytes32);
|
||||||
|
|
||||||
|
function wrappedAsset(uint16 tokenChainId, bytes32 tokenAddress) external view returns (address);
|
||||||
|
|
||||||
|
function bridgeContracts(uint16 chainId_) external view returns (bytes32);
|
||||||
|
|
||||||
|
function tokenImplementation() external view returns (address);
|
||||||
|
|
||||||
|
function WETH() external view returns (IWETH);
|
||||||
|
|
||||||
|
function outstandingBridged(address token) external view returns (uint256);
|
||||||
|
|
||||||
|
function isWrappedAsset(address token) external view returns (bool);
|
||||||
|
|
||||||
|
function finality() external view returns (uint8);
|
||||||
|
|
||||||
|
function implementation() external view returns (address);
|
||||||
|
|
||||||
|
function initialize() external;
|
||||||
|
|
||||||
|
function registerChain(bytes memory encodedVM) external;
|
||||||
|
|
||||||
|
function upgrade(bytes memory encodedVM) external;
|
||||||
|
|
||||||
|
function submitRecoverChainId(bytes memory encodedVM) external;
|
||||||
|
|
||||||
|
function parseRegisterChain(bytes memory encoded) external pure returns (RegisterChain memory chain);
|
||||||
|
|
||||||
|
function parseUpgrade(bytes memory encoded) external pure returns (UpgradeContract memory chain);
|
||||||
|
|
||||||
|
function parseRecoverChainId(bytes memory encodedRecoverChainId) external pure returns (RecoverChainId memory rci);
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
// contracts/Bridge.sol
|
||||||
|
// SPDX-License-Identifier: Apache 2
|
||||||
|
|
||||||
|
pragma solidity ^0.8.0;
|
||||||
|
|
||||||
|
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||||
|
|
||||||
|
interface IWETH is IERC20 {
|
||||||
|
function deposit() external payable;
|
||||||
|
function withdraw(uint amount) external;
|
||||||
|
}
|
|
@ -9,11 +9,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||||
|
|
||||||
import "../../libraries/external/BytesLib.sol";
|
import "../../libraries/external/BytesLib.sol";
|
||||||
import "../../interfaces/IWormhole.sol";
|
import "../../interfaces/IWormhole.sol";
|
||||||
|
import "../interfaces/ITokenBridge.sol";
|
||||||
interface ITokenBridge {
|
|
||||||
function completeTransferWithPayload(bytes memory encodedVm) external returns (bytes memory);
|
|
||||||
function wrappedAsset(uint16 tokenChainId, bytes32 tokenAddress) external view returns (address);
|
|
||||||
}
|
|
||||||
|
|
||||||
contract MockTokenBridgeIntegration {
|
contract MockTokenBridgeIntegration {
|
||||||
using BytesLib for bytes;
|
using BytesLib for bytes;
|
||||||
|
|
|
@ -3,10 +3,80 @@
|
||||||
|
|
||||||
pragma solidity ^0.8.0;
|
pragma solidity ^0.8.0;
|
||||||
|
|
||||||
import "../Structs.sol";
|
interface IWormhole {
|
||||||
|
struct GuardianSet {
|
||||||
|
address[] keys;
|
||||||
|
uint32 expirationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Signature {
|
||||||
|
bytes32 r;
|
||||||
|
bytes32 s;
|
||||||
|
uint8 v;
|
||||||
|
uint8 guardianIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VM {
|
||||||
|
uint8 version;
|
||||||
|
uint32 timestamp;
|
||||||
|
uint32 nonce;
|
||||||
|
uint16 emitterChainId;
|
||||||
|
bytes32 emitterAddress;
|
||||||
|
uint64 sequence;
|
||||||
|
uint8 consistencyLevel;
|
||||||
|
bytes payload;
|
||||||
|
|
||||||
|
uint32 guardianSetIndex;
|
||||||
|
Signature[] signatures;
|
||||||
|
|
||||||
|
bytes32 hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ContractUpgrade {
|
||||||
|
bytes32 module;
|
||||||
|
uint8 action;
|
||||||
|
uint16 chain;
|
||||||
|
|
||||||
|
address newContract;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GuardianSetUpgrade {
|
||||||
|
bytes32 module;
|
||||||
|
uint8 action;
|
||||||
|
uint16 chain;
|
||||||
|
|
||||||
|
GuardianSet newGuardianSet;
|
||||||
|
uint32 newGuardianSetIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SetMessageFee {
|
||||||
|
bytes32 module;
|
||||||
|
uint8 action;
|
||||||
|
uint16 chain;
|
||||||
|
|
||||||
|
uint256 messageFee;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TransferFees {
|
||||||
|
bytes32 module;
|
||||||
|
uint8 action;
|
||||||
|
uint16 chain;
|
||||||
|
|
||||||
|
uint256 amount;
|
||||||
|
bytes32 recipient;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RecoverChainId {
|
||||||
|
bytes32 module;
|
||||||
|
uint8 action;
|
||||||
|
|
||||||
|
uint256 evmChainId;
|
||||||
|
uint16 newChainId;
|
||||||
|
}
|
||||||
|
|
||||||
interface IWormhole is Structs {
|
|
||||||
event LogMessagePublished(address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel);
|
event LogMessagePublished(address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel);
|
||||||
|
event ContractUpgraded(address indexed oldContract, address indexed newContract);
|
||||||
|
event GuardianSetAdded(uint32 indexed index);
|
||||||
|
|
||||||
function publishMessage(
|
function publishMessage(
|
||||||
uint32 nonce,
|
uint32 nonce,
|
||||||
|
@ -14,29 +84,59 @@ interface IWormhole is Structs {
|
||||||
uint8 consistencyLevel
|
uint8 consistencyLevel
|
||||||
) external payable returns (uint64 sequence);
|
) external payable returns (uint64 sequence);
|
||||||
|
|
||||||
function parseAndVerifyVM(bytes calldata encodedVM) external view returns (Structs.VM memory vm, bool valid, string memory reason);
|
function initialize() external;
|
||||||
|
|
||||||
function verifyVM(Structs.VM memory vm) external view returns (bool valid, string memory reason);
|
function parseAndVerifyVM(bytes calldata encodedVM) external view returns (VM memory vm, bool valid, string memory reason);
|
||||||
|
|
||||||
function verifySignatures(bytes32 hash, Structs.Signature[] memory signatures, Structs.GuardianSet memory guardianSet) external pure returns (bool valid, string memory reason) ;
|
function verifyVM(VM memory vm) external view returns (bool valid, string memory reason);
|
||||||
|
|
||||||
function parseVM(bytes memory encodedVM) external pure returns (Structs.VM memory vm);
|
function verifySignatures(bytes32 hash, Signature[] memory signatures, GuardianSet memory guardianSet) external pure returns (bool valid, string memory reason);
|
||||||
|
|
||||||
function getGuardianSet(uint32 index) external view returns (Structs.GuardianSet memory) ;
|
function parseVM(bytes memory encodedVM) external pure returns (VM memory vm);
|
||||||
|
|
||||||
function getCurrentGuardianSetIndex() external view returns (uint32) ;
|
function quorum(uint numGuardians) external pure returns (uint numSignaturesRequiredForQuorum);
|
||||||
|
|
||||||
function getGuardianSetExpiry() external view returns (uint32) ;
|
function getGuardianSet(uint32 index) external view returns (GuardianSet memory);
|
||||||
|
|
||||||
function governanceActionIsConsumed(bytes32 hash) external view returns (bool) ;
|
function getCurrentGuardianSetIndex() external view returns (uint32);
|
||||||
|
|
||||||
function isInitialized(address impl) external view returns (bool) ;
|
function getGuardianSetExpiry() external view returns (uint32);
|
||||||
|
|
||||||
function chainId() external view returns (uint16) ;
|
function governanceActionIsConsumed(bytes32 hash) external view returns (bool);
|
||||||
|
|
||||||
|
function isInitialized(address impl) external view returns (bool);
|
||||||
|
|
||||||
|
function chainId() external view returns (uint16);
|
||||||
|
|
||||||
|
function isFork() external view returns (bool);
|
||||||
|
|
||||||
function governanceChainId() external view returns (uint16);
|
function governanceChainId() external view returns (uint16);
|
||||||
|
|
||||||
function governanceContract() external view returns (bytes32);
|
function governanceContract() external view returns (bytes32);
|
||||||
|
|
||||||
function messageFee() external view returns (uint256) ;
|
function messageFee() external view returns (uint256);
|
||||||
|
|
||||||
|
function evmChainId() external view returns (uint256);
|
||||||
|
|
||||||
|
function nextSequence(address emitter) external view returns (uint64);
|
||||||
|
|
||||||
|
function parseContractUpgrade(bytes memory encodedUpgrade) external pure returns (ContractUpgrade memory cu);
|
||||||
|
|
||||||
|
function parseGuardianSetUpgrade(bytes memory encodedUpgrade) external pure returns (GuardianSetUpgrade memory gsu);
|
||||||
|
|
||||||
|
function parseSetMessageFee(bytes memory encodedSetMessageFee) external pure returns (SetMessageFee memory smf);
|
||||||
|
|
||||||
|
function parseTransferFees(bytes memory encodedTransferFees) external pure returns (TransferFees memory tf);
|
||||||
|
|
||||||
|
function parseRecoverChainId(bytes memory encodedRecoverChainId) external pure returns (RecoverChainId memory rci);
|
||||||
|
|
||||||
|
function submitContractUpgrade(bytes memory _vm) external;
|
||||||
|
|
||||||
|
function submitSetMessageFee(bytes memory _vm) external;
|
||||||
|
|
||||||
|
function submitNewGuardianSet(bytes memory _vm) external;
|
||||||
|
|
||||||
|
function submitTransferFees(bytes memory _vm) external;
|
||||||
|
|
||||||
|
function submitRecoverChainId(bytes memory _vm) external;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
// contracts/NFTBridge.sol
|
||||||
|
// SPDX-License-Identifier: Apache 2
|
||||||
|
|
||||||
|
pragma solidity ^0.8.0;
|
||||||
|
|
||||||
|
import "../../interfaces/IWormhole.sol";
|
||||||
|
|
||||||
|
interface INFTBridge {
|
||||||
|
struct Transfer {
|
||||||
|
bytes32 tokenAddress;
|
||||||
|
uint16 tokenChain;
|
||||||
|
bytes32 symbol;
|
||||||
|
bytes32 name;
|
||||||
|
uint256 tokenID;
|
||||||
|
string uri;
|
||||||
|
bytes32 to;
|
||||||
|
uint16 toChain;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SPLCache {
|
||||||
|
bytes32 name;
|
||||||
|
bytes32 symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RegisterChain {
|
||||||
|
bytes32 module;
|
||||||
|
uint8 action;
|
||||||
|
uint16 chainId;
|
||||||
|
|
||||||
|
uint16 emitterChainID;
|
||||||
|
bytes32 emitterAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UpgradeContract {
|
||||||
|
bytes32 module;
|
||||||
|
uint8 action;
|
||||||
|
uint16 chainId;
|
||||||
|
|
||||||
|
bytes32 newContract;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RecoverChainId {
|
||||||
|
bytes32 module;
|
||||||
|
uint8 action;
|
||||||
|
|
||||||
|
uint256 evmChainId;
|
||||||
|
uint16 newChainId;
|
||||||
|
}
|
||||||
|
|
||||||
|
event ContractUpgraded(address indexed oldContract, address indexed newContract);
|
||||||
|
|
||||||
|
function transferNFT(address token, uint256 tokenID, uint16 recipientChain, bytes32 recipient, uint32 nonce) external payable returns (uint64 sequence);
|
||||||
|
|
||||||
|
function completeTransfer(bytes memory encodeVm) external;
|
||||||
|
|
||||||
|
function encodeTransfer(Transfer memory transfer) external pure returns (bytes memory encoded);
|
||||||
|
|
||||||
|
function parseTransfer(bytes memory encoded) external pure returns (Transfer memory transfer);
|
||||||
|
|
||||||
|
function onERC721Received(address operator, address, uint256, bytes calldata) external view returns (bytes4);
|
||||||
|
|
||||||
|
function governanceActionIsConsumed(bytes32 hash) external view returns (bool);
|
||||||
|
|
||||||
|
function isInitialized(address impl) external view returns (bool);
|
||||||
|
|
||||||
|
function isTransferCompleted(bytes32 hash) external view returns (bool);
|
||||||
|
|
||||||
|
function wormhole() external view returns (IWormhole);
|
||||||
|
|
||||||
|
function chainId() external view returns (uint16);
|
||||||
|
|
||||||
|
function evmChainId() external view returns (uint256);
|
||||||
|
|
||||||
|
function isFork() external view returns (bool);
|
||||||
|
|
||||||
|
function governanceChainId() external view returns (uint16);
|
||||||
|
|
||||||
|
function governanceContract() external view returns (bytes32);
|
||||||
|
|
||||||
|
function wrappedAsset(uint16 tokenChainId, bytes32 tokenAddress) external view returns (address);
|
||||||
|
|
||||||
|
function bridgeContracts(uint16 chainId_) external view returns (bytes32);
|
||||||
|
|
||||||
|
function tokenImplementation() external view returns (address);
|
||||||
|
|
||||||
|
function isWrappedAsset(address token) external view returns (bool);
|
||||||
|
|
||||||
|
function splCache(uint256 tokenId) external view returns (SPLCache memory);
|
||||||
|
|
||||||
|
function finality() external view returns (uint8);
|
||||||
|
|
||||||
|
function initialize() external;
|
||||||
|
|
||||||
|
function implementation() external view returns (address);
|
||||||
|
|
||||||
|
function registerChain(bytes memory encodedVM) external;
|
||||||
|
|
||||||
|
function upgrade(bytes memory encodedVM) external;
|
||||||
|
|
||||||
|
function submitRecoverChainId(bytes memory encodedVM) external;
|
||||||
|
|
||||||
|
function parseRegisterChain(bytes memory encoded) external pure returns(RegisterChain memory chain);
|
||||||
|
|
||||||
|
function parseUpgrade(bytes memory encoded) external pure returns(UpgradeContract memory chain);
|
||||||
|
|
||||||
|
function parseRecoverChainId(bytes memory encodedRecoverChainId) external pure returns (RecoverChainId memory rci);
|
||||||
|
}
|
Loading…
Reference in New Issue