SwiftGate contracts

Swift Gate - 0xB84f07612F4bfEc42E042b6CDD26df496b3d397f

The swift gate smart contract is responsible for bridging tokens between different blockchains. The governors whitelist tokens on a certain chain id that can be bridged to other chain ids.

Users call swiftSend() to bridge tokens to other chain and specify if they want the swiftReceive()call on the destination chain to be batched with other users bridged tokens or not. Calling swiftSend() with the isSingle_ argument to true will inccur in much bigger gas costs, but instant bridging, whereas setting this flag to false is slower but about 6 times cheaper.

The governors, each running the backend, sign a transaction specifying tokens to be received on the destination chain after users call swiftSend() in the source chain.

Validating 13 signatures is an expensive process and to compensate for this, swift gate leverages batching user deposits so that for a batch of bridged tokens only a message hash has to be signed. For example, for each bridged token, a regular bridge would require 2 transactions, one on the source chain and one on the destination chain, having to validate 13 signatures once. In this case, for 10 deposits, it would require 20 transactions in which the signatures are validated 10 times. However, if the bridged assets are batched, it takes 11 transactions (10 swiftSend() + 1 swiftReceive()) and the signatures are only validate once.

The governors are rewarded with yield from depositing the bridged assets into Aave. They can call functions depositToAave() and withdrawFromAave() to claim their rewards.

Token Factory - 0xDBAF1e8f67B63a1DA2f9bB0214d6087cAA58170D

The token factory creates wrapped tokens for tokens on other blockchains. Its owner is the swift gate, from which governors can create new wrapped tokens.

The tokens are clones, which means that they have a common implementation as SwiftERC20. When a token is created on the token factory, it deploys a proxy which points to the implementation, effectively reducing gas costs significantly for the governors.

SwiftERC20 - 0x46972365C218484d1286B6Ea08d35bD5aaa935C4

Implementation of wrapped tokens of the swift gate. Regular ERC20 token that is mintable and burnable by the swift gate. When a token not native to a blockchain is received, the receiver is minted wrapped tokens. When the user wants to bridge back the tokens, these are burned and they get the remote tokens on the original blockchain.

Smart Contracts Architecture

alt text imageUrl

SwiftERC20

Git Source

Inherits: ERC20Upgradeable

State Variables

_swiftGate

address of the swift gate contract

address internal _swiftGate;

_remoteToken

address of the remote token contract

address internal _remoteToken;

Functions

onlySwiftGate

can only be called by swift gate

modifier onlySwiftGate();

initialize

initialize the contract

function initialize(string memory name_, string memory symbol_, address swiftGate_, address remoteToken_)
    public
    initializer;

Parameters

NameTypeDescription
name_stringname of the wrapped token
symbol_stringsymbol of the wrapped token
swiftGate_addressaddress of the swift gate contract
remoteToken_addressaddress of the remote token contract

mint

swift gate mints tokens

function mint(address account_, uint256 amount_) external onlySwiftGate;

Parameters

NameTypeDescription
account_addressaddress to mint tokens to
amount_uint256amount of tokens to mint

burn

swift gate burns tokens

function burn(address account_, uint256 amount_) external onlySwiftGate;

Parameters

NameTypeDescription
account_addressaddress to burn tokens from
amount_uint256amount of tokens to burn

getSwiftGate

returns the address of the swift gate

function getSwiftGate() external view returns (address);

getRemoteToken

returns the address of the remote token

function getRemoteToken() external view returns (address);

Errors

OnlySwiftGateError

triggered when an address other than the swift gate calls this contract

error OnlySwiftGateError(address msgSender_);

SwiftGate

Git Source

State Variables

_chainId

chain id of swift gate on this chain

uint16 internal _chainId;

_aaveV3LendingPool

Aave v3 lending pool

IPool internal _aaveV3LendingPool;

_aaveV3RewardsController

Aave v3 rewards controller

IRewardsController internal _aaveV3RewardsController;

_governors

Mapping of governor address => is governor

mapping(address => bool) internal _governors;

_feeOfChainId

Mapping of chainId => fee

mapping(uint256 => uint256) internal _feeOfChainId;

_feeIfBatchedOfChainId

Mapping of chainId => fee if batched

mapping(uint256 => uint256) internal _feeIfBatchedOfChainId;

_signedMessages

Mapping of chainId => is chain supported

mapping(bytes32 => bool) internal _signedMessages;

_remoteToWrappedTokens

Mapping of chainId => destination token => wrappedToken

mapping(uint256 => mapping(address => address)) internal _remoteToWrappedTokens;

_wrappedToRemoteTokens

Mapping of token to wrapped token

mapping(address => address) internal _wrappedToRemoteTokens;

_dstTokens

Mapping of chainId => local token => is supported token

mapping(uint256 => mapping(address => bool)) internal _dstTokens;

_tokenFactory

Factory for creating wrapped tokens

TokenFactory internal immutable _tokenFactory;

_minSignatures

Minimum signatures to validate messages

uint256 internal _minSignatures;

Functions

constructor

creates the TokenFactory which is owner by this contract - swift gate

constructor();

initialize

initializes the swift gate contract

function initialize(
    uint16 chainId_,
    address aaveV3,
    address aaveV3RewardsController_,
    address[] memory governors_,
    uint256 minSignatures_
) external;

Parameters

NameTypeDescription
chainId_uint16chain id of the swift gate contract
aaveV3addressaave v3 lending pool address
aaveV3RewardsController_addressaave v3 rewards controller address
governors_address[]array of governor addresses
minSignatures_uint256minimum number of signatures to validate messages

swiftReceive

receives a batch of tokens, mints the wrapped versions and verifies the signatures.

function swiftReceive(SwReceiveParams[] calldata params_, Signature[] calldata signatures_, bytes32 salt_) external;

Parameters

NameTypeDescription
params_SwReceiveParams[]struct with the parameters to sned across bridges - includes token, amount, receiver, srcChain, dstChain
signatures_Signature[]array of signatures from the governors (message hash signed by governors )
salt_bytes32salt used to enable signing the same message more than once

swiftSend

sends a token to another chain.

function swiftSend(address token_, uint256 amount_, address receiver_, uint16 dstChain_, bool isSingle_) external;

Parameters

NameTypeDescription
token_addressthe token to send.
amount_uint256the amount of tokens to send.
receiver_addressthe receiver of the tokens.
dstChain_uint16the destination chain.
isSingle_boolwhether the token is to be batched with other tokens to save gas or not.

addWrappedToken

adds a wrapped token to the respective mapping so it can be used across chains

function addWrappedToken(
    uint16 chainId_,
    address token_,
    string memory name_,
    string memory symbol_,
    Signature[] calldata signatures_,
    bytes32 salt_
) external;

Parameters

NameTypeDescription
chainId_uint16chain id of the wrapped token
token_addresstoken that is being wrapped
name_stringname of the wrapped token
symbol_stringsymbol of the wrapped token
signatures_Signature[]array of signatures from the governors (message hash signed by governors )
salt_bytes32salt used to enable signing the same message more than once

addDstToken

Adds a token to the dstTokens mapping (verified with the signatures). Signals that a token can be bridged to another chain

function addDstToken(uint16 chainId_, address token_, Signature[] calldata signatures_, bytes32 salt_) external;

Parameters

NameTypeDescription
chainId_uint16chain id of the token
token_addresstoken that is being added
signatures_Signature[]array of signatures from the governors (message hash signed by governors )
salt_bytes32salt used to enable signing the same message more than once

depositToAaveV3

deposits a given token in the aave lending pool

function depositToAaveV3(address token_, uint256 amount_, Signature[] calldata signatures_, bytes32 salt_) external;

Parameters

NameTypeDescription
token_addresstoken to be deposited
amount_uint256amount to be deposited
signatures_Signature[]array of signatures from the governors (message hash signed by governors )
salt_bytes32salt used to enable signing the same message more than once

withdrawFromAaveV3

withdraws tokens and rewards from aave to claim the yield for the governors

function withdrawFromAaveV3(
    address token_,
    address aToken_,
    uint256 amount_,
    address receiver_,
    Signature[] calldata signatures_,
    bytes32 salt_
) external;

Parameters

NameTypeDescription
token_addresstoken to be withdrawn
aToken_addresscorresponding aave token. Required for the rewards controller
amount_uint256amount to be withdrawn
receiver_addressaddress to receive the tokens
signatures_Signature[]array of signatures from the governors (message hash signed by governors )
salt_bytes32salt used to enable signing the same message more than once

setFeeOfChainId

sets the fee for a given chain id

function setFeeOfChainId(uint16 chainId_, uint256 fee_, Signature[] calldata signatures_, bytes32 salt_) external;

Parameters

NameTypeDescription
chainId_uint16chain id to set the fee for
fee_uint256fee to be set
signatures_Signature[]array of signatures from the governors (message hash signed by governors )
salt_bytes32salt used to enable signing the same message more than once

setFeeIfBatchedOfChainId

sets the fee if the swiftSend call is batched for a given chain id. Much cheaper than single fee

function setFeeIfBatchedOfChainId(
    uint16 chainId_,
    uint256 feeIfBatched_,
    Signature[] calldata signatures_,
    bytes32 salt_
) external;

Parameters

NameTypeDescription
chainId_uint16chain id to set the fee for
feeIfBatched_uint256fee to be set
signatures_Signature[]array of signatures from the governors (message hash signed by governors )
salt_bytes32salt used to enable signing the same message more than once

setGovernors

sets the governors of the swift gate. Useful if governors are not working well and need to be replaced

function setGovernors(
    address[] calldata governors_,
    bool[] calldata set_,
    Signature[] calldata signatures_,
    bytes32 salt_
) external;

Parameters

NameTypeDescription
governors_address[]array of governors to be set
set_bool[]array of booleans to set the governors to true or false
signatures_Signature[]array of signatures from the governors (message hash signed by governors )
salt_bytes32salt used to enable signing the same message more than once

setMinSignatures

sets the min signatures required to execute calls to the swift gate

function setMinSignatures(uint256 minSignatures_, Signature[] calldata signatures_, bytes32 salt_) external;

Parameters

NameTypeDescription
minSignatures_uint256min signatures to be set
signatures_Signature[]array of signatures from the governors (message hash signed by governors )
salt_bytes32salt used to enable signing the same message more than once

getFeeOfChainId

gets the single swift send fee of to a given chain id

function getFeeOfChainId(uint16 chainId_) external view returns (uint256);

Parameters

NameTypeDescription
chainId_uint16chain id to get the fee for

getFeeIfBatchedOfChainId

gets the batched swift send fee of to a given chain id

function getFeeIfBatchedOfChainId(uint16 chainId_) external view returns (uint256);

Parameters

NameTypeDescription
chainId_uint16chain id to get the fee for

getChainId

gets the chain id of the swift gate

function getChainId() external view returns (uint256);

isGovernor

checks if an account is a governor

function isGovernor(address account_) external view returns (bool);

Parameters

NameTypeDescription
account_addressaccount to check

Returns

NameTypeDescription
<none>booltrue if the account is a governor, false otherwise

getWrappedToken

gets the wrapped token of a given chain id and token address

function getWrappedToken(uint16 chainId_, address token_) external view returns (address);

Parameters

NameTypeDescription
chainId_uint16chain id to get the wrapped token for
token_addresstoken to get the wrapped token for

Returns

NameTypeDescription
<none>addresswrapped token address

getTokenFactory

gets the token factory address that creates the wrapped tokens

function getTokenFactory() external view returns (address);

Returns

NameTypeDescription
<none>addresstoken factory address

getRemoteTokenOf

gets the remote token of a given wrapped token address

function getRemoteTokenOf(address wrappedToken_) external view returns (address);

Parameters

NameTypeDescription
wrappedToken_addresswrapped token to get the remote token for

Returns

NameTypeDescription
<none>addressremote token address

isDstToken

checks if a token is allowed to be bridged to a destination chain id

function isDstToken(uint16 chainId_, address token_) external view returns (bool);

Parameters

NameTypeDescription
chainId_uint16chain id to check
token_addresstoken to check

Returns

NameTypeDescription
<none>booltrue if the token is allowed to be bridged, false otherwise

getMinSignatures

gets the min signatures required to execute calls to the swift gate

function getMinSignatures() external view returns (uint256);

getAaveV3LendingPool

gets the aave v3 lending pool address

function getAaveV3LendingPool() external view returns (address);

_verifySignatures

function _verifySignatures(bytes32 messageHash_, Signature[] calldata signatures_) internal;

Events

SwiftSend

emitted when an account calls swiftSend and bridges to the destination chain

event SwiftSend(address token, address remoteToken_, uint256 amount, address receiver, uint16 dstChain, bool isSingle);

Errors

LengthMismatchError

triggered when the lengths of the array arguments don't match

error LengthMismatchError();

NotEnoughSignaturesError

triggered when the number of signatures is less than the minimum

error NotEnoughSignaturesError();

InvalidSignatureError

triggered when the signature is invalid

error InvalidSignatureError();

WrontDstChainError

error WrontDstChainError(uint256 chainId);

UnsupportedTokenError

triggered when the token is not supported on a certain destination chain

error UnsupportedTokenError(uint16 chainId, address token);

ZeroAddressError

triggered on a zero address argument

error ZeroAddressError();

ZeroAmountError

triggered when the amount is zero

error ZeroAmountError();

ChainIdAlreadySetError

triggered when the chain id is already set. Prevents reinitialization

error ChainIdAlreadySetError();

DuplicateSignatureError

triggered when the signature is a duplicate. Prevents message replay

error DuplicateSignatureError();

Structs

Signature

Struct to hold signature data

struct Signature {
    uint8 v;
    bytes32 r;
    bytes32 s;
}

SwReceiveParams

Struct to hold swift receive parameters

struct SwReceiveParams {
    address token;
    uint256 amount;
    address receiver;
    uint16 srcChain;
    uint16 dstChain;
}

TokenFactory

Git Source

State Variables

_implementation

implementation of the swiftGate wrapped tokens

address internal immutable _implementation;

_swiftGate

address of the swift gate contract

address internal immutable _swiftGate;

Functions

onlySwiftGate

can only be called by swift gate

modifier onlySwiftGate();

constructor

the swift gate creates the token factory in its constructor.

constructor();

create

create a new wrapped token. Called by the swift gate

function create(string memory name_, string memory symbol_, address remoteToken_)
    external
    onlySwiftGate
    returns (address proxy_);

Parameters

NameTypeDescription
name_stringname of the wrapped token
symbol_stringsymbol of the wrapped token
remoteToken_addressaddress of the remote token contract

getImplementation

returns the address of the implementation of the wrapped tokens

function getImplementation() external view returns (address);

Errors

OnlySwiftGateError

triggered when an address other than the swift gate calls this contract

error OnlySwiftGateError(address msgSender_);