Speedbump

Overview of mechanism design of speedbump

SpeedBump

Table of Contents

  1. Specification

  2. Parameters

  3. Functions

    1. initialize

    2. batchRegisterNFTs

    3. batchWithdrawNFTs

    4. registerToken

    5. withdrawToken

    6. registerETH

    7. withdrawETH

  4. Events

Specification

The speedBump contract acts as a temporary holder of ERC-20's and ERC-721's when they are withdrawn from the pool. It forces the user to wait until the next block to remove liquidity. This is done to reduce the risk of exploits that make use of flash loans. Flash loans revert if all liquidity + fees are not returned in the same block, thus the speedBump makes a flash loan exploit less likely.

Register Withdrawal ERC-721:

  1. The positionManager sends the NFT (ERC-721) to the SpeedBump contract.

  2. The positionManager calls a function on the SpeedBump contract to register the withdrawal request, providing the user’s address and the current block number. This is protected by nonReentrant modifier

User Withdraw (ERC-721)

  1. The user sends a message to `withdrawNft`` with tokenID.

  2. If the user has a deposit on the speedBump, and the current block number is at least the block number at registration + 1, the NFT will be transfered to the user

Depositing ERC-20

  1. The positionManager sends the ERC-20 to the SpeedBump contract.

  2. The position manager call registerToken with the ERC-20 token address and an amount of the token, registering it to the user in a withdrawl struct

Withdraw ERC-20

  1. The user sends a message to withdrawToken with the associated address of the ERC-20 contract.

  2. If the block number is at least the block number registered in the withdraw struct + 1, the ERC-20 is withdrawn to the user. This is protected by the non-reentrant modifier.

Parameters

struct ETH {
    uint256 blockNumber;
    uint256 amount;
}

struct Token {
    uint256 blockNumber;
    uint256 amount;
}

struct NFT {
    uint256 blockNumber;
    address owner;
}

// owner address => ETH
mapping(address => ETH) public eths;

// token address => owner address => Token
mapping(address => mapping(address => Token)) public tokens;

// collection address => nft id => NFT
mapping(address => mapping(uint256 => NFT)) public collections;

Functions

initialize

The initialize takes as an argument the associated address for the position Manager. The functions "registerXXXX" have a modifier that makes it so they can only be called by the positionManager.

function initialize(address _positionManager) public initializer {
    positionManager = _positionManager;
}

batchRegisterNFTs

/**
* @notice Batch register nft when withdrawing(removing liquidity) from SeacowsPositionManager
* @param collection The collection address to register then store
* @param tokenIds The NFT ids to register then store
* @param owner The address that own the NFTs.
*/
function batchRegisterNFTs(
    address collection,
    uint256[] memory tokenIds,
    address owner
) public onlyPositionManager nonReentrant

batchWithdrawNFTs

/**
* @notice Batch withdraw nft from SpeedBump contract
* @param collection The collection address user want to withdraw
* @param tokenIds The NFT ids user want to withdraw
*/
function batchWithdrawNFTs(
    address collection, 
    uint256[] memory tokenIds
) public nonReentrant

registerToken

/*
* @dev Register token when withdrawing(removing liquidity) from SeacowsPositionManager
* @param owner The address that own the token.
* @param token The token contract address.
* @param amount The token amount store in contract.
*/
function registerToken(
    address token, 
    uint256 amount, 
    address owner
) public onlyPositionManager nonReentrant

withdrawToken

/**
* @notice Withdraw all token from SpeedBump contract
* @param token The token address user want to withdraw
*/
function withdrawToken(
    address token
) public nonReentrant

registerETH

/*
* @dev Register ETH when withdrawing(removing liquidity) from SeacowsPositionManager
* @param owner The address that own the ETH.
* @param amount The eth amount store in contract.
*/
function registerETH(
    uint256 amount, 
    address owner
) public onlyPositionManager nonReentrant

withdrawETH

/**
* @notice Withdraw all ETH from SpeedBump contract
*/
function withdrawETH() public nonReentrant

Events

/*
* @dev Emit at the end of the registerETH function call
* @param owner The address that own the ETH.
* @param amount The eth amount store in contract.
*/
event RegisterETH(
    address indexed owner, 
    uint256 amount
);

/*
* @dev Emit at the end of the registerToken function call
* @param owner The address that own the token.
* @param token The token contract address.
* @param amount The token amount store in contract.
*/
event RegisterToken(
    address indexed owner, 
    address indexed token, 
    uint256 amount
);

/*
* @dev Emit at the end of the batchRegisterNFTs function call
* @param owner The address that own the nft.
* @param collection The collection contract address.
* @param tokenIds The nft ids store in contract.
*/
event RegisterNFTs(
    address indexed owner, 
    address indexed collection, 
    uint256[] tokenIds
);

/*
* @dev Emit at the end of the withdrawETH function call
* @param sender The address that send the withdraw request.
* @param amount The eth amount user withdraw.
*/
event WithdrawETH(
    address indexed sender, 
    uint256 amount
);

/*
* @dev Emit at the end of the withdrawToken function call
* @param sender The address that send the withdraw request.
* @param token The token contract address.
* @param amount The eth amount user want to withdraw.
*/
event WithdrawToken(
    address indexed sender, 
    address indexed token, 
    uint256 amount
);

/*
* @dev Emit at the end of the batchWithdrawNFTs function call
* @param sender The address that send the withdraw request.
* @param collection The collection contract address.
* @param tokenIds The nft ids user want to withdraw.
*/
event WithdrawNFTs(
    address indexed sender, 
    address indexed collection, 
    uint256[] tokenIds
);

Last updated