GC withdrawal contract
Background
From Spec Gnosis Chain withdrawals #1
- During block processing, state transition must call
WITHDRAWAL_CONTRACT
function
- If transaction reverts, the block is invalid. So if a specific state (i.e. not enough funds) causes a revert in all cases, the network halts
Deposit flow
- Bridge GNO from mainnet to Gnosis Chain
- Swap GNO for mGNO
- Deposit mGNO to deposit contract
Contract deployments
Withdrawal flow
If the system transaction reverts due to lack of funds the chain halts. If the system is temporarily insolvent, which transaction should revert and when? To ensure the contract never reverts:
- Allow the contract to mint some token, so it never runs out of funds
- Queue the withdrawal action for latter processing with chosen mechanism
- Add indirection, require the user to claim funds with a transaction that can safely revert
- (unsafe) always pre-fund with maximum possible withdrawn value. This in potentially impossible since the deposit flow is unbounded given long enough timescales
Flow A: auto-transfer + queue
- System transaction:
- Execution client calls withdrawal contract
- Withdrawal contract calls checks for mGNO solvency:
- If solvent:
- Clear max of X pending withdrawals from queued state, then
transfer
on mGNO contract to target address, or
- (optional) withdrawal contract unwraps mGNO to GNO and transfers GNO to target address
- If insolvent:
- Add block's withdrawals to pending withdrawals contract state
Withdrawal contract must be pre-funded but lack of funds do not halt the chain. After a period of insolvency, queue is cleared automatically during block processing. No input is required by users in any case.
Flow B: user initiated claim
- System transaction:
- Execution client calls withdrawal contract
- Withdrawal contract adds allowance to target address for withdrawal amount
- User transaction
- User calls
claim
on withdrawal contract
- (optional) withdrawal contract unwraps mGNO to GNO and transfers to user
If the system is not properly funded the second transaction will revert, but the chain will not halt. Requires an action on the user to obtain the funds. Allows the user to choose to claim mGNO or GNO.
Flow C: mGNO mint
- System transaction:
- Execution client calls withdrawal contract
- Withdrawal contract mints mGNO to target address
- 2.1. User unwraps mGNO to GNO (reverts if wrapper contract insolvent)
Source of funds
Numbers from Jan 26 2023
- SBC wrapper proxy mGNO: (145,337 GNO ~ 15,382,523 USD)
- Deposit contract: holds staked mGNO (3,646,880 mGNO ~ 113,965 GNO).
- GNO on xDAI: current supply =
Reward payout solvency estimation
Withdrawal contract should have access to the deposit contract such that the principal of the stake is always available.
Staking rewards must be supplied externally. This section estimates their upper bound:
- Deposit inflows are technically unbounded in the Gnosis Chain. The practical upper bound is the entire supply of GNO.
- TODO: APY estimation for Gnosis Beacon Chain
Withdrawal contract
- System transaction that unwraps automatically to GNO
- There should be an admin variable to switch to not unwrap
- In the case the transfer fails, store withdrawable amount in a map. That value is claimable by the withdrawee, but can triggered by anyone
- The WITHDRAWAL_CONTRACT = DEPOSIT_CONTRACT, to prevent need of allowances
- WITHDRAWAL_CONTRACT may never became insolvent, as its a ponzi new deposit inflows pay for outflows, deposit contract balance may not
- There must exist a way to topup the contract without triggering a deposit