DexBook contracts

Steps to deploy

  • run make install
  • copy .env.example to .env
  • fill PRIVATE_KEY
  • run make deploy-apothem

Smart Contract Addresses

WBTC/USDC - 0x78a82ACE5c7133918ca7Be3DB3EAb3a1046232AC

WETH/USDC - 0x8734c402782382E6eC48638Fc64A11C4DCcdDce1

WBTC/WETH - 0xE002bc2Eab8dE575a372D13eD5ABAAb206ABb0ba

WBTC - 0x11b33c8bf6b3147ea0e913dB15b82c125eAcA7Bf

USDC - 0xf83234CC66Da5502bFEC9A7f6b8807b3A171e4db

WETH - 0x17ff834DaFD183f06D68a2ea01cFAad9092ED779

Contents

LibLinkedOrders

Git Source

State Variables

NULL

NULL is a constant that represents an invalid order id

uint48 internal constant NULL = uint48(0);

Functions

insert

inserts an order at the bottom of a linked list of orders

function insert(LinkedOrders storage self, address maker_, uint256 amount_) internal returns (uint48 orderId_);

Parameters

NameTypeDescription
selfLinkedOrdersis the linked list of orders
maker_addressis the address of the order maker
amount_uint256is the amount of token to be traded

remove

removes an order from a linked list of orders

function remove(LinkedOrders storage self, uint48 id_) internal returns (bool, address, uint256);

Parameters

NameTypeDescription
selfLinkedOrdersis the linked list of orders
id_uint48is the id of the order to be removed

modify

modifies the amount of an order

function modify(LinkedOrders storage self, uint48 id_, uint256 newAmount_) internal returns (address, uint256);

Parameters

NameTypeDescription
selfLinkedOrdersis the linked list of orders
id_uint48is the id of the order to be modified
newAmount_uint256is the new amount of the order

removeUntilTarget

removes orders from a linked list of orders until the target amount is reached. Useful to fulfill market orders

deletes orders until the target amount is reached in the while loop. If the target amount is reached after removing the last order, returns. Else, does a partial fulfillment of the last order, if it exists

function removeUntilTarget(
    LinkedOrders storage self,
    uint256 targetAmount_,
    uint128 price_,
    function(uint48,uint128, address,uint256) internal _f
) internal returns (uint256, bool);

Parameters

NameTypeDescription
selfLinkedOrdersis the linked list of orders
targetAmount_uint256is the cummulative amount to be removed
price_uint128is the price of the order
_ffunction (uint48, uint128, address, uint256) internalis the function to be called when an order is removed

getOrders

returns the orders in a linked list of orders

function getOrders(LinkedOrders storage self) internal view returns (ViewOrder[] memory orders_);

Parameters

NameTypeDescription
selfLinkedOrdersis the linked list of orders

Errors

OrderDoesNotExistError

OrderDoesNotExistError is emitted when an order does not exist

error OrderDoesNotExistError();

Structs

Order

Order is a struct that contains the maker, amount, and price of an order.

struct Order {
    address maker;
    uint48 prev;
    uint48 next;
    uint256 amount;
}

ViewOrder

ViewOrder is a struct that contains the id, maker, and amount of an order.

struct ViewOrder {
    uint48 id;
    address maker;
    uint256 amount;
}

LinkedOrders

LinkedOrders is a struct that contains the head, tail, and length of a linked list of orders.

struct LinkedOrders {
    uint48 head;
    uint48 tail;
    uint48 length;
    mapping(uint48 => Order) orders;
}

LibPriceBrackets

Git Source

State Variables

PRICE_PRECISION

price precision is required because solidity does not support decimal values

uint128 internal constant PRICE_PRECISION = 10 ** 18;

NULL

NULL price

uint128 internal constant NULL = uint128(0);

Functions

insertOrder

function insertOrder(
    PriceBrackets storage self,
    uint128 price_,
    address maker_,
    uint256 amount_,
    uint128[] calldata prevs_,
    uint128[] calldata nexts_
) internal returns (uint48 orderId_);

Parameters

NameTypeDescription
selfPriceBracketsthe price bracket with the list of orders
price_uint128the price of the order that the market order maker will have to pay
maker_addressthe address of the order maker
amount_uint256the amount of token that will be sent to the maker
prevs_uint128[]hints for the closest existing previous prices
nexts_uint128[]hints for the closest existing next prices

removeOrder

removes an order from the price bracket

function removeOrder(PriceBrackets storage self, uint128 price_, uint48 orderId_) internal returns (address, uint256);

Parameters

NameTypeDescription
selfPriceBracketsthe price bracket with the list of orders
price_uint128the price of the order that the market order maker would have to pay
orderId_uint48the id of the order to remove

Returns

NameTypeDescription
<none>addressmaker_ the address of the order maker
<none>uint256amount_ the amount of token that will be sent to the maker

modifyOrder

modifies an order from the price bracket

function modifyOrder(PriceBrackets storage self, uint128 price_, uint48 orderId_, uint256 newAmount_)
    internal
    returns (address, uint256);

Parameters

NameTypeDescription
selfPriceBracketsthe price bracket with the list of orders
price_uint128the price of the order that the market order maker will have to pay
orderId_uint48the id of the order to modify
newAmount_uint256the new amount of token that will be sent to the maker

Returns

NameTypeDescription
<none>addressmaker_ the address of the order maker
<none>uint256amount_ the amount of token that will be sent to the maker

removeOrdersUntilTarget

removes orders from the price bracket until the target amount is reached

when a market order is placed, it fills limit orders until the target

function removeOrdersUntilTarget(
    PriceBrackets storage self,
    uint256 targetAmount_,
    function(uint48,uint128,address,uint256) internal _f
) internal returns (uint256 accumulatedAmount_, uint256 accumulatedCost_);

Parameters

NameTypeDescription
selfPriceBracketsthe price bracket with the list of orders
targetAmount_uint256the target amount to reach
_ffunction (uint48, uint128, address, uint256) internalthe function to call for each order removed

Returns

NameTypeDescription
accumulatedAmount_uint256the accumulated amount summed by filling orders. Might not reach the target
accumulatedCost_uint256the accumulated cost for the market order maker to pay

exists

checks if a price bracket exists

function exists(PriceBrackets storage self, uint128 price_) internal view returns (bool);

Parameters

NameTypeDescription
selfPriceBracketsthe price bracket with the list of orders
price_uint128the price of the order that the market order maker will have to pay

Returns

NameTypeDescription
<none>boolexists_ true if the price bracket exists

_findClosestPrev

finds the closest previous price bracket to the price

function _findClosestPrev(PriceBrackets storage self, uint128[] calldata prevs_, uint128 price_)
    internal
    view
    returns (uint128 prev_);

Parameters

NameTypeDescription
selfPriceBracketsthe price bracket with the list of orders
prevs_uint128[]the list of previous prices to find the closest previous price
price_uint128the price of the order that the market order maker will have to pay

Returns

NameTypeDescription
prev_uint128the closest previous price bracket

_findClosestNext

finds the closest next price bracket to the price

function _findClosestNext(PriceBrackets storage self, uint128[] calldata nexts_, uint128 price_)
    internal
    view
    returns (uint128 next_);

Parameters

NameTypeDescription
selfPriceBracketsthe price bracket with the list of orders
nexts_uint128[]the list of next prices to find the closest next price
price_uint128the price of the order that the market order maker will have to pay

Returns

NameTypeDescription
next_uint128the closest next price bracket

getPrices

used to fetch the price brackets off chain. Converts the linked list to an array

function getPrices(PriceBrackets storage self) internal view returns (uint128[] memory prices_);

Parameters

NameTypeDescription
selfPriceBracketsthe price bracket with the list of orders

Returns

NameTypeDescription
prices_uint128[]an array with all the price brackets

getOrdersAtPrice

gets the orders at a specific price bracket

function getOrdersAtPrice(PriceBrackets storage self, uint128 price_)
    internal
    view
    returns (LibLinkedOrders.ViewOrder[] memory);

Parameters

NameTypeDescription
selfPriceBracketsthe price bracket with the list of orders
price_uint128the price of the order that the market order maker will have to pay

Returns

NameTypeDescription
<none>LibLinkedOrders.ViewOrder[]orders_ an array with all the orders at the price bracket

getOrderAtPrice

gets the order at a specific price bracket and order id

function getOrderAtPrice(PriceBrackets storage self, uint128 price_, uint48 orderId_)
    internal
    view
    returns (LibLinkedOrders.Order memory);

Parameters

NameTypeDescription
selfPriceBracketsthe price bracket with the list of orders
price_uint128the price of the order that the market order maker will have to pay
orderId_uint48the id of the order

Returns

NameTypeDescription
<none>LibLinkedOrders.Orderorder_ the order at the price bracket and order id

getOrdersAndPrices

gets all the orders in every price bracket

used to fetch all the orders off chain. Converts the linked lists to an array of OrdersByPrice

function getOrdersAndPrices(PriceBrackets storage self)
    internal
    view
    returns (OrdersByPrice[] memory correctOrdersByPrices_);

Parameters

NameTypeDescription
selfPriceBracketsthe price bracket with the list of orders

Returns

NameTypeDescription
correctOrdersByPrices_OrdersByPrice[]an array with all the orders at the price bracket

Errors

PriceSmallerThanPrevError

emitted when the hints are wrong and the current price is bigger than the previous hinted price

error PriceSmallerThanPrevError();

PriceBiggerThanNextError

emitted when the hints are wrong and the current price is smaller than the next hinted price

error PriceBiggerThanNextError();

PriceBracketDoesNotExistError

emitted when the price bracket does not exist

error PriceBracketDoesNotExistError();

Structs

OrdersByPrice

OrdersByPrice is a struct that contains the price and an array of orders at that price

useful to fetch off chain all orders at a given price

struct OrdersByPrice {
    uint128 price;
    LibLinkedOrders.ViewOrder[] orders;
}

PriceBracket

PriceBracket is a struct that contains the previous and next price brackets and a linked list of orders

a linked list is used to allow insertion and removal of orders in constant time (given hints)

struct PriceBracket {
    uint128 prev;
    uint128 next;
    LibLinkedOrders.LinkedOrders linkedOrders;
}

PriceBrackets

PriceBrackets is a struct that contains the lowest and highest price and a mapping of price to price bracket

contains the head (lowest price) and tail (highest price) of the linked list of price brackets

struct PriceBrackets {
    uint128 lowestPrice;
    uint128 highestPrice;
    mapping(uint128 => PriceBracket) priceBrackets;
}

Contents

FaucetERC20

Git Source

Inherits: ERC20

Functions

constructor

constructor(string memory symbol_, string memory name_) ERC20(symbol_, name_);

faucet

function faucet() external;

USDC

Git Source

Inherits: FaucetERC20

Functions

constructor

constructor() FaucetERC20("USD Coin", "USDC");

decimals

function decimals() public view virtual override returns (uint8);

USDT

Git Source

Inherits: FaucetERC20

Functions

constructor

constructor() FaucetERC20("Tether USD", "USDT");

decimals

function decimals() public view virtual override returns (uint8);

WBTC

Git Source

Inherits: FaucetERC20

Functions

constructor

constructor() FaucetERC20("Wrapped BTC", "WBTC");

WETH

Git Source

Inherits: FaucetERC20

Functions

constructor

constructor() FaucetERC20("Wrapped Ether", "WETH");

DexBook

Git Source

State Variables

PRICE_PRECISION

price precision is required to represent prices below 0

uint128 internal constant PRICE_PRECISION = 10 ** 18;

BASIS_POINT

basis point is 1/100 of a percent

uint256 internal constant BASIS_POINT = 10 ** 4;

_protocolFee

protocol fee is 10 basis points or 0.1%

uint256 internal constant _protocolFee = 10;

_tokenADecimals

caches tokenA decimals to save on gas costs

uint256 internal immutable _tokenADecimals;

_tokenBDecimals

caches tokenB decimals to save on gas costs

uint256 internal immutable _tokenBDecimals;

_tokenA

token A of this address

address internal immutable _tokenA;

_tokenB

token B of this address

address internal immutable _tokenB;

_feeRecipient

address that receives protocol fees

address internal immutable _feeRecipient;

_buyOrders

stores all buy orders

LibPriceBrackets.PriceBrackets internal _buyOrders;

_sellOrders

stores all sell orders

LibPriceBrackets.PriceBrackets internal _sellOrders;

Functions

constructor

constructor of the contract. Sets the tokenA and tokenB

constructor(address tokenA_, address tokenB_);

Parameters

NameTypeDescription
tokenA_addressthe tokenA
tokenB_addressthe tokenB

placeBuyLimitOrder

function placeBuyLimitOrder(uint256 amount_, uint128 price_, uint128[] calldata prevs_, uint128[] calldata nexts_)
    external
    returns (uint48 orderId_);

Parameters

NameTypeDescription
amount_uint256tokenA amount to buy
price_uint128tokenB/tokenA, not considering decimals, with PRICE_PRECISION
prevs_uint128[]hints for the previous price bracket
nexts_uint128[]hints for the next price bracket

placeSellLimitOrder

function placeSellLimitOrder(uint256 amount_, uint128 price_, uint128[] calldata prevs_, uint128[] calldata nexts_)
    external
    returns (uint48 orderId_);

Parameters

NameTypeDescription
amount_uint256tokenB amount to sell
price_uint128tokenA/tokenB, not considering decimals, with PRICE_PRECISION
prevs_uint128[]hints for the previous price bracket
nexts_uint128[]hints for the next price bracket

placeBuyMarketOrder

buys tokenA with tokenB at the best available price

function placeBuyMarketOrder(uint256 tokenBamount_) external;

Parameters

NameTypeDescription
tokenBamount_uint256amount of tokenB used to buy tokenA

placeSellMarketOrder

buys tokenB with tokenA at the best available price

function placeSellMarketOrder(uint256 tokenAamount_) external;

Parameters

NameTypeDescription
tokenAamount_uint256amount of tokenA used to buy tokenB

removeBuyLimitOrder

removes a buy limit order from the order book

function removeBuyLimitOrder(uint48 orderId_, uint128 price_) external;

Parameters

NameTypeDescription
orderId_uint48id of the order to remove
price_uint128tokenB/tokenA, not considering decimals, with PRICE_PRECISION

removeSellLimitOrder

removes a sell limit order from the order book

function removeSellLimitOrder(uint48 orderId_, uint128 price_) external;

Parameters

NameTypeDescription
orderId_uint48id of the order to remove
price_uint128tokenA/tokenB, not considering decimals, with PRICE_PRECISION

modifyBuyLimitOrder

modifies a buy limit order

reverts if the new price and amount are the same as the old ones

function modifyBuyLimitOrder(
    uint48 orderId_,
    uint128 oldPrice_,
    uint128 newPrice_,
    uint256 newAmount_,
    uint128[] calldata prevs_,
    uint128[] calldata nexts_
) external returns (uint48);

Parameters

NameTypeDescription
orderId_uint48id of the order to modify
oldPrice_uint128old tokenB/tokenA, not considering decimals, with PRICE_PRECISION
newPrice_uint128new tokenB/tokenA, not considering decimals, with PRICE_PRECISION
newAmount_uint256new amount of tokenA to buy
prevs_uint128[]hints for the previous price bracket
nexts_uint128[]hints for the next price bracket

modifySellLimitOrder

modifies a sell limit order

reverts if the new price and amount are the same as the old ones

function modifySellLimitOrder(
    uint48 orderId_,
    uint128 oldPrice_,
    uint128 newPrice_,
    uint256 newAmount_,
    uint128[] calldata prevs_,
    uint128[] calldata nexts_
) external returns (uint48);

Parameters

NameTypeDescription
orderId_uint48id of the order to modify
oldPrice_uint128old tokenA/tokenB, not considering decimals, with PRICE_PRECISION
newPrice_uint128new tokenA/tokenB, not considering decimals, with PRICE_PRECISION
newAmount_uint256new amount of tokenA to buy
prevs_uint128[]hints for the previous price bracket
nexts_uint128[]hints for the next price bracket

tokenAToTokenB

returns tokenB from a tokenA argument and a tokenB/tokenA price

function tokenAToTokenB(uint256 amount_, uint256 price_) public view returns (uint256);

Parameters

NameTypeDescription
amount_uint256amount of tokenA to convert
price_uint256tokenB/tokenA price, not considering decimals, with PRICE_PRECISION

Returns

NameTypeDescription
<none>uint256amount of tokenB

tokenBToTokenA

returns tokenA from a tokenB argument and a tokenA/tokenB price

function tokenBToTokenA(uint256 amount_, uint256 price_) public view returns (uint256);

Parameters

NameTypeDescription
amount_uint256amount of tokenB to convert
price_uint256tokenA/tokenB price, not considering decimals, with PRICE_PRECISION

Returns

NameTypeDescription
<none>uint256amount of tokenA

tokenAToTokenBDecimals

converts tokenA decimals to tokenB decimals

function tokenAToTokenBDecimals(uint256 amount_) public view returns (uint256);

Parameters

NameTypeDescription
amount_uint256amount of tokenA to convert

Returns

NameTypeDescription
<none>uint256amount of tokenB

tokenBToTokenADecimals

converts tokenB decimals to tokenA decimals

function tokenBToTokenADecimals(uint256 amount_) public view returns (uint256);

Parameters

NameTypeDescription
amount_uint256amount of tokenB to convert

Returns

NameTypeDescription
<none>uint256amount of tokenA

pricePrecision

returns the precision used in the prices

function pricePrecision() external pure returns (uint128);

Returns

NameTypeDescription
<none>uint128precision

tokenA

returns tokenA address

function tokenA() external view returns (address);

Returns

NameTypeDescription
<none>addresstokenA address

tokenB

returns tokenB address

function tokenB() external view returns (address);

Returns

NameTypeDescription
<none>addresstokenB address

tokenADecimals

returns tokenA decimals

function tokenADecimals() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256tokenA decimals

tokenBDecimals

returns tokenB decimals

function tokenBDecimals() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256tokenB decimals

protocolFee

returns the protocol fee

function protocolFee() external pure returns (uint256);

Returns

NameTypeDescription
<none>uint256protocol fee

feeRecipient

returns the address of the fee recipient

function feeRecipient() external view returns (address);

Returns

NameTypeDescription
<none>addressfee recipient

sellOrdersPrices

returns the priceBrackets of the sell orders

function sellOrdersPrices() external view returns (uint128[] memory prices_);

Returns

NameTypeDescription
prices_uint128[]priceBrackets of the sell orders

buyOrdersPrices

returns the priceBrackets of the buy orders

function buyOrdersPrices() external view returns (uint128[] memory prices_);

Returns

NameTypeDescription
prices_uint128[]priceBrackets of the buy orders

sellOrdersAtPrice

returns the sell orders at a given price

function sellOrdersAtPrice(uint128 price_) external view returns (LibLinkedOrders.ViewOrder[] memory orders_);

Parameters

NameTypeDescription
price_uint128tokenA/tokenB price, not considering decimals, with PRICE_PRECISION

Returns

NameTypeDescription
orders_LibLinkedOrders.ViewOrder[]ordered sell orders array at a given price

buyOrdersAtPrice

returns the buy orders at a given price

function buyOrdersAtPrice(uint128 price_) external view returns (LibLinkedOrders.ViewOrder[] memory orders_);

Parameters

NameTypeDescription
price_uint128tokenA/tokenB price, not considering decimals, with PRICE_PRECISION

Returns

NameTypeDescription
orders_LibLinkedOrders.ViewOrder[]ordered buy orders array at a given price

sellOrderAtPrice

returns the sell order at a given price and order id

function sellOrderAtPrice(uint128 price_, uint48 orderId_)
    external
    view
    returns (LibLinkedOrders.Order memory order_);

Parameters

NameTypeDescription
price_uint128tokenA/tokenB price, not considering decimals, with PRICE_PRECISION
orderId_uint48order id

Returns

NameTypeDescription
order_LibLinkedOrders.Ordersell order at a given price and order id

buyOrderAtPrice

returns the buy order at a given price and order id

function buyOrderAtPrice(uint128 price_, uint48 orderId_) external view returns (LibLinkedOrders.Order memory order_);

Parameters

NameTypeDescription
price_uint128tokenB/tokenA price, not considering decimals, with PRICE_PRECISION
orderId_uint48order id

Returns

NameTypeDescription
order_LibLinkedOrders.Orderbuy order at a given price and order id

sellOrdersAndPrices

returns the sell orders and corresponding prices

function sellOrdersAndPrices() external view returns (LibPriceBrackets.OrdersByPrice[] memory orders_);

Returns

NameTypeDescription
orders_LibPriceBrackets.OrdersByPrice[]sell orders and corresponding prices

buyOrdersAndPrices

returns the buy orders and corresponding prices

function buyOrdersAndPrices() external view returns (LibPriceBrackets.OrdersByPrice[] memory orders_);

Returns

NameTypeDescription
orders_LibPriceBrackets.OrdersByPrice[]buy orders and corresponding prices

invertPrice

inverts a price, taking into account PRICE_PRECISION

function invertPrice(uint128 price_) external pure returns (uint128);

Parameters

NameTypeDescription
price_uint128price with PRICE_PRECISION to invert

amountPlusFee

returns the amount + protocol fee

function amountPlusFee(uint256 amount_) external pure returns (uint256);

Parameters

NameTypeDescription
amount_uint256amount to add the protocol fee

Returns

NameTypeDescription
<none>uint256amount + protocol fee

basisPoint

returns the basis point - 1/100th percent

function basisPoint() external pure returns (uint256);

Returns

NameTypeDescription
<none>uint256basis point

_fulfillBuyLimitOrder

function _fulfillBuyLimitOrder(uint48 orderId_, uint128 price_, address maker_, uint256 amount_) internal;

_fulfillSellLimitOrder

function _fulfillSellLimitOrder(uint48 orderId_, uint128 price_, address maker_, uint256 amount_) internal;

Events

BuyLimitOrderPlaced

emitted when a buy limit order is placed

event BuyLimitOrderPlaced(uint48 indexed orderId, uint128 indexed price, address indexed maker, uint256 amount);

SellLimitOrderPlaced

emitted when a sell limit order is placed

event SellLimitOrderPlaced(uint48 indexed orderId, uint128 indexed price, address indexed maker, uint256 amount);

BuyLimitOrderCancelled

emitted when a buy limit order is cancelled

event BuyLimitOrderCancelled(uint48 indexed orderId, uint128 indexed price, address indexed maker, uint256 amount);

SellLimitOrderCancelled

emitted when a sell limit order is cancelled

event SellLimitOrderCancelled(uint48 indexed orderId, uint128 indexed price, address indexed maker, uint256 amount);

BuyLimitOrderFilled

emitted when a buy limit order is filled

event BuyLimitOrderFilled(uint48 indexed orderId, uint128 indexed price, address indexed maker, uint256 amount);

SellLimitOrderFilled

emitted when a sell limit order is filled

event SellLimitOrderFilled(uint48 indexed orderId, uint128 indexed price, address indexed maker, uint256 amount);

BuyLimitOrderModified

emitted when a buy limit order is modified

event BuyLimitOrderModified(
    uint48 indexed orderId, uint128 indexed price, address indexed maker, uint256 oldAmount, uint256 amount
);

SellLimitOrderModified

emitted when a sell limit order is modified

event SellLimitOrderModified(
    uint48 indexed orderId, uint128 indexed price, address indexed maker, uint256 oldAmount, uint256 amount
);

BuyMarketOrderFilled

emitted when a buy market order is filled

event BuyMarketOrderFilled(uint256 timestamp, uint256 indexed price, address indexed maker, uint256 amount);

SellMarketOrderFilled

emitted when a sell market order is filled

event SellMarketOrderFilled(uint256 timestamp, uint256 indexed price, address indexed maker, uint256 amount);

Errors

SameAmountError

emitted when modifying an order with stale new same price and amount

error SameAmountError(uint256 amount);

OnlyMakerError

emitted when someone other than the maker tries to remove or modify an order

error OnlyMakerError(address maker);