import HistoricalFact from './_gpv2.md'
GPv2VaultRelayer
Architecture
The GPv2VaultRelayer
contract is an important component used to protect user funds from malicious solvers. As previously mentioned, the GPv2Settlement
contract allows using arbitrary on-chain liquidity through interactions (such as performing a swap on Balancer V2, or performing a Paraswap trade). If Vault
and ERC20
allowances were made directly to a GPv2Settlement
contract, a malicious solver could drain user funds through the interaction mechanism. However, since these allowances are made to the GPv2VaultRelayer
contract and interactions to the contract are strictly forbidden, malicious solvers have no direct access to user funds. The GPv2Settlement
contract uses the GPv2VaultRelayer
to withdraw user tokens only as part of the trade, which contains strong guarantees that the user's signed order parameters are respected.
The GPv2VaultRelayer
has access to user balances through 3 mechanisms:
Guarantees and Invariants
- The
GPv2VaultRelayer
is only able to transferERC20
tokens to theGPv2Settlement
contract
Fallback ERC20 Allowances
The third and final method of approving tokens for CoW protocol is to use direct ERC20
allowances to the GPv2VaultRelayer
. This works like most other trading protocols, where for each token you want to sell, an allowance must first be approved for the GPv2VaultRelayer
contract.
Orders with the sellTokenBalance
flag set to erc20
will withdraw using this process. The buyTokenBalance
flag can also be set to erc20
in order to receive trade proceeds directly in ERC20
amounts.
Balancer External Balances
The first mechanism that the GPv2VaultRelayer
contract can use to withdraw user ERC20
tokens is through Vault
external balances. This works by having an ERC20
allowance for the Balancer Vault, and a relayer approval for the GPv2VaultRelayer
contract.
This allowance and approval combination allows the GPv2VaultRelayer
contract to transfer ERC20
tokens through the Vault
. Roughly speaking, the process works in the following way:
GPv2VaultRelayer
request to the Balancer Vault anERC20
transfer from the user account to theGPv2Settlement
contract- The Balancer Vault verifies that the
GPv2VaultRelayer
contract is:
a. Authorized by Balancer governance to act as a relayer
b. The user has set an approval for that specific relayer - The Balancer Vault issues an
ERC20
transfer from the user account to theGPv2Settlement
contract using the Vault's existingERC20
allowance
This system for withdrawing user funds has several advantages such as:
- It can reuse existing
Vault
ERC20
allowances and doesn't require new ones specific to the CoW Protocol. - Upgrades to the CoW Protocol contract would only require a single relayer approval for all tokens instead of individual
ERC20
approvals for each token being traded. - The
GPv2VaultRelayer
approval can be revoked by a single transaction to theVault
instead of multiple transactions to eachERC20
token for which the user wants to remove the approval.
Orders with the sellTokenBalance
flag set to external
will withdraw using this process.
Balancer Internal Balances
The second mechanism is to use balances internal to the Vault
. The Balancer V2 vault can accrue ERC20
token balances and keep track of them internally in order to allow extremely gas-efficient transfers and swaps. The CoW Protocol contracts can make use of this in order to decrease the gas cost of settling a user order on-chain. In order for this to work, the user must approve the GPv2VaultRelayer
contract and have internal Vault
balances available.
Internal balances can be withdrawn from the Vault
at any time for their ERC20
equivalent amounts.
Orders with the sellTokenBalance
flag set to internal
will withdraw using this process. The buyTokenBalance
flag can also be set to internal
in order to receive trade proceeds in internal balances instead of ER20
token balances.
Data Types and Storage
Nil
Functions
For the Protocol
transferFromAccounts
This function is used for transferring ERC20
tokens from users to the GPv2Settlement
contract in the course of settling a batch auction.
function transferFromAccounts(
GPv2Transfer.Data[] calldata transfers
) external onlyCreator {
vault.transferFromAccounts(transfers, msg.sender);
}
batchSwapWithFee
This function is used in the course of settling a single trade on-chain. It is called by the GPv2Settlement
contract and is used to perform a batch swap on the Balancer V2 vault. The function is defined as:
function batchSwapWithFee(
IVault.SwapKind kind,
IVault.BatchSwapStep[] calldata swaps,
IERC20[] memory tokens,
IVault.FundManagement memory funds,
int256[] memory limits,
uint256 deadline,
GPv2Transfer.Data calldata feeTransfer
) external onlyCreator returns (int256[] memory tokenDeltas)
Indexing
Nil
Off-chain
Nil