Smart Contract trading

The Ethereum Virtual Machine (EVM) differes between user accounts, also known as Externally Owned Accounts (EOAs), and Smart Contract accounts. An EOA cannot have code deployed to it and a Smart Contract account cannot have a private key, that is owned by a user.

Since Orderly Network uses EIP-712 off-chain signatures for trading, which will be sent to our backend services, a Smart Contract account cannot trade using this method. In order to allow Smart Contracts to trade on our platform, we introduce a feature called “Delegate Signer”, that allows delegation of trading for a Smart Contract account to be executed by an EOA.

Delegate Signer allows Smart Contracts to assign an EOA to sign on behalf of them for actions requiring the EIP-712 signature. Smart Contracts assign a Delegate Signer through Orderly Network’s Vault Smart Contract function called delegateSigner prior to interacting with Orderly.

Limitations

There can only be one EOA per Smart Contract account. If a new Delegate Signer is announced via Vault Smart Contract interaction, the old Delegate Signer will be deleted.

Smart Contract accounts are single chain accounts, restricted to only be able to deposit/withdraw from the chain the Delegate Signer call was made.

A Smart Contract account will always need an EOA to withdraw funds.

Implementation

1

Create delegate signer link

Your Smart Contract needs to call the delegateSigner function on the Orderly Vault contract. The interface is described below:

function delegateSigner(VaultTypes.VaultDelegate calldata data) external;

library VaultTypes {
    struct VaultDelegate {
        bytes32 brokerHash;
        address delegateSigner;
    }
}

Latest contract ABI files can be found on our GitHub. All of our contracts are verified, so you can also see the ABI on their respective explorers.

An example Smart Contract deployed on Arbitrum Sepolia has the following code to initiate delegation:

pragma solidity ^0.8.18;

import "./IVault.sol";

contract DelegateContract {
    function execAction(address to, uint256 value, bytes memory action) public returns (bool success) {
        uint256 gasLeft = gasleft();
         assembly {
            success := call(gasLeft, to, value, add(action, 0x20), mload(action), 0, 0)
        }
    }

    function delegate(address vault, VaultTypes.VaultDelegate calldata data) public {
        IVault(vault).delegateSigner(data);
    }
}

After calling the function on your Smart Contract for the linking, you need to remember this transaction hash.

2

Accept the link from the Delegate Signer EOA

Confirm the link by signing the EIP-712 with your Delegate Signer’s wallet and send the information via delegate_signer API. You will also need to send the transaction hash from previous step.

This step will optionally create the account for the Smart Contract, if it does not yet exist. If it already exists it will just update the linked EOA account.

3

Add Orderly Key

Add Delegate Orderly Key via REST API.

4

Deploy funds

You can either implement a function in your Smart Contract to call the deposit function of the Vault contract or you can call the depositTo function from any address and deposit into your Smart Contract’s account wallet. For the latter you will also require the account_id from the registration step.

5

Start Trading

Start trading via regular trading APIs authenticated with above Orderly Key.

6

Settle PnL/Withdraw

Settle PnL and withdraw via special Delegate Signer endpoints. Sign EIP-712 domains with Delegate Signer wallet.

Example

A full example can be found on this Github repository. The website is deployed here.