SIP 116: Optimism standard deposit/withdrawal interface Source

AuthorAlejandro Santander, Yannis Stamelakos

Simple Summary

Optimism is defining a new standard for deposit/withdrawal bridges between L1 and L2. This standard defines the function names and signatures for depositing tokens into L2, as well as for withdrawing them back to L1. We should update our contracts to adopt this new standard.


The proposed changes involve renaming a few functions and events in two of our contracts as well as adding minor functionality to them to be able to deposit and withdraw SNX for another address. The contracts will need to be redeployed, and SynthetixBridgeToOptimism’s SNX balance will beed to be migrated to the new L1 bridge contract.


As Optimism’s L2 gains adoption, more and more tokens will begin to move accross the layers. One example of this is the official WETH token to be used in place of ETH in Optimism’s mainnet, which will comply to the deposit/withdrawal interface standard. Unless these changes are applied, Synthetix’s bridges will need to be interacted with in a different way to all the other bridges. Another reason to migrate now is that a migration in the future could involve the migration of a much larger SNX value.



Migrate our L1 and L2 bridges, SynthetixBridgeToOptimism and SynthetixBridgeToBase to conform to Optimism’s standard deposit/withdrawal interface.


First, changes should be made to SynthetixBridgeToOptimism and SynthetixBridgeToBase. Following that, the corresponding test cases should be updated, and tests should be written to cover new functionality. Finally, the two contracts should be deployed on each layer, and linked to the system. The bridge in L1 is particularly sensitive because it locks a large number of funds.

Technical Specification

SynthetixBridgeToOptimism should adopt iOVM_L1ERC20Gateway:

interface iOVM_L1ERC20Gateway {
    function deposit(uint _amount) external;

    function depositTo(address _to, uint _amount) external;

    function finalizeWithdrawal(address _to, uint _amount) external;

    event DepositInitiated(address indexed _from, address _to, uint256 _amount);

    event WithdrawalFinalized(address indexed _to, uint256 _amount);

SynthetixBridgeToBase should adopt iOVM_L2DepositedERC20:

interface iOVM_L2DepositedERC20 is IUniswapV2ERC20 {
    function withdraw(uint _amount) external;

    function withdrawTo(address _to, uint _amount) external;

    function finalizeDeposit(address _to, uint _amount) external;

    event WithdrawalInitiated(address indexed _from, address _to, uint256 _amount);

    event DepositFinalized(address indexed _to, uint256 _amount);

The bridges should implement these interface, as well as the previously existing ISynthetixBridgeToOptimism and ISynthetixBridgeToBase interfaces.

The new interface for SynthetixBridgeToOptimism should be:

interface ISynthetixBridgeToOptimism {
    function migrateEscrow(uint256[][] calldata entryIDs) external;

    function depositReward(uint amount) external;

    function depositAndMigrateEscrow(uint256 depositAmount, uint256[][] calldata entryIDs) external;

The new interface for SynthetixBridgeToBase should be:

interface ISynthetixBridgeToBase {
    function finalizeEscrowMigration(
        address account,
        uint256 escrowedAmount,
        VestingEntries.VestingEntry[] calldata vestingEntries
    ) external;

    function finalizeRewardDeposit(uint amount) external;

SynthetixBridgeToOptimism’s SNX balance will need to be migrated to the new SynthetixBridgeToOptimism contract, which will be achieved by calling the following function in the old contract:

migrateBridge(address newBridge) ( To ensure the safety of this migration, a script will be used, ensuring:

  • That the new bridge address is valid
  • That the new bridge address is a contract
  • That the new bridge owner is the same as the old one
  • That the old bridge balance is not zero
  • That the new bridge balance is zero

Additionally, the migration will be tested on a fork of mainnet before official execution on mainnet.

Test Cases

All existing tests will be renamed accordingly.

New test cases:

  • depositTo(address to, uint256 amount)
    • Same as deposit(uint256 amount) amount, with
    • msg.sender is account1
    • to is account2
    • amount is deduced from account1’s balance in L1
    • amount is minted for account2 on L2
  • withdrawTo(address to, uint256 amount)
    • Same as withdraw(uint256 amount) amount, with
    • msg.sender is account1
    • to is account2
    • amount is deduced from account1’s balance in L2
    • amount is released for account2 on L1

Configurable Values (Via SCCP)

No new configurable values are involved with the proposed changes.

Copyright and related rights waived via CC0.