Log In

Code for LiminalMarket smart contract can be found on github
https://github.com/liminal-market/liminal.market.contracts/blob/main/contracts/LiminalMarket.sol

Below you can see the documentation for 4 main functions in the contract.

  • buyWithAUSD
  • sellSecurityToken
  • executeOrder
  • createToken

buyWithAUSD

The buyWithAUsd function is a Solidity function that allows a user to buy a security token using aUsd. The function takes in 4 input parameters:

  • address walletAddress: The address of the user's wallet where the security token will be transferred to.
  • address tokenAddress: The address of the security token contract the user wants to buy.
  • uint256 amount: The amount of aUsd the user wants to spend on buying the security token.
  • address spender: The address of the spender of the buy order execution. The spender is a smart contract by a 3rd party DeFi service

The function starts by checking that the caller of the function is the aUsd contract using the require statement and the ONLY_AUSD_CAN_CALL_ME constant. If the caller is not the aUsd contract it will revert the transaction. Then it checks that market is open by calling the isMarketOpen() function on the marketCalendarContract variable and if the market is closed it will revert the transaction.

The function then retrieves the user's aUsd balance using the balanceOf() function on the aUsdContract variable and checks that the balance is greater than or equal to the amount input using the require statement and the NOT_ENOUGH_AUSD constant. If the user doesn't have enough aUsd, the transaction will be reverted.

The function then retrieves the user's accountId by calling the isValid() function on the kycContract variable and passing in the walletAddress input.

The function then retrieves the security token contract at the tokenAddress input and assigns it to a variable securityToken of type SecurityToken. It checks that the owner of the security token is the contract itself using the require statement and the NOT_VALID_TOKEN_ADDRESS constant.

The function then retrieves the symbol of the security token using the symbol() function on the securityToken variable and if the spender address is zero address, it assigns the spender address as the contract address.

The function ends by emitting a BuyWithAUsd event, passing in the walletAddress, amount, accountId, symbol, tokenAddress, and spender as arguments, and calling the setBalance function on the aUsdContract variable, passing in the walletAddress, ausdBalance - amount, and Action.OrderBuy enum as arguments.

sellSecurityToken

The sellSecurityToken function is a Solidity function that allows a user to sell a security token for aUsd. The function takes in 5 input parameters:

  • address walletAddress: The address of the user's wallet where the security token is coming from.
  • address aUsdAddress: The address of the aUsd contract to where the aUsd will be transferred.
  • string memory symbol: The symbol of the security token the user wants to sell.
  • uint quantity: The amount of the security token the user wants to sell.
  • address spender: The address of the spender of the sell order execution. The spender is a smart contract by a 3rd party DeFi service

The function starts by checking that the aUsdAddress input is the address of the aUsd contract using the require statement and the ONLY_SEND_TO_AUSD constant. If the aUsdAddress is not the address of the aUsd contract, the transaction will be reverted. Then it checks that the market is open by calling the isMarketOpen() function on the marketCalendarContract variable and if the market is closed it will revert the transaction.

The function then calls the getSecurityToken(symbol) function and checks that the returned address is the address of the contract calling the function using the require statement and the NOT_VALID_TOKEN_ADDRESS constant. If the security token address is not the address of the contract calling the function, the transaction will be reverted.

The function then retrieves the user's accountId by calling the isValid() function on the kycContract variable and passing in the walletAddress input.

The function then retrieves the security token contract that is calling the function and assigns it to a variable token of type SecurityToken. It retrieves the balance of the security token for the user's wallet address using the balanceOf() function on the token variable and checks that the balance is greater than or equal to the quantity input using the require statement and the QUANTITY_MORE_THEN_BALANCE constant. If the user's balance is less than the quantity, the transaction will be reverted.

The function then checks if the spender address is zero address, it assigns the spender address as the contract address.

The function ends by emitting a SellSecurityToken event, passing in the accountId, walletAddress, aUsdAddress, symbol, quantity, and spender as arguments, and calling the setBalance function on the token variable, passing in the walletAddress, balance - quantity, and Action.OrderSell enum as arguments.

executeOrder

The orderExecuted function is a Solidity function that performs several actions when called. The function takes in 9 input parameters:

  • address recipient: The address of the recipient of the order execution.
  • string memory symbol: The symbol of the security token that the order is being executed for, e.g .AAPL
  • uint tsl: Stands for Total shares locked. This the total quantity of share that is registered to the user.
  • uint filledQty: The quantity of the security token that was filled in the order execution.
  • uint filledAvgPrice: The average price of the security token that was filled in the order execution.
  • string memory side: The side of the order execution ("buy" or "sell").
  • uint filledAt: The timestamp of when the order execution took place.
  • uint commission: The commission from the order execution.
  • uint aUsdBalance: The balance of the aUsd.
  • address spender: The address of the spender of the order execution.

The function starts by checking that the recipient address is not the zero address using the require statement and ADDRESS_CANNOT_BE_ZERO constant, if the recipient is zero address it will revert the transaction. Then it declares a variable st of type SecurityToken.

The function then looks up the address of the security token specified by the symbol input using the securityTokens mapping. If the token address is the zero address, it creates a new token using the createToken function. Otherwise, it retrieves the existing token from the contract at the given address.

The function then calls the setBalance function on the st variable, passing in the recipient, tsl, and Action.OrderExecuted enum as arguments. It also calls the setBalance function on the aUsdContract variable, passing in the recipient, aUsdBalance, and Action.OrderExecuted enum as arguments.

The function ends by emitting an OrderExecuted event, passing in all of the input parameters as arguments.

It's also worth noting that this function is only callable when the contract is not paused and the caller has the MINTER_ROLE.

createToken

This is a Solidity function named "createToken" that creates and returns a new "SecurityToken" contract. The function takes in a single input, a "string memory" type named "symbol". The function is marked as "external" and can only be called when not paused

The function begins by checking if the "symbol" input is not empty using the "require" function and an assertion that the length of bytes of "symbol" is not equal to 0. If this condition is not met, an error message (SYMBOL_CANNOT_BE_EMPTY) is thrown.

The function then checks if a "SecurityToken" contract with the same "symbol" already exists by checking if the "securityTokens[symbol]" variable, is equal to the address 0. If it is not equal to 0, it throws an error message TOKEN_ALREADY_EXISTS.

If both of these checks pass, the function creates a new "SecurityToken" contract using the "new" keyword and passing in two inputs: "TOKEN_NAME" and the "symbol" input. It then declares a variable "tokenAddress" which is set to the address of the newly created contract. The function then stores the address of the contract in the "securityTokens[symbol]" mapping and emits an event named "TokenCreated" with the token address and symbol as inputs.

Finally, the function returns the newly created "SecurityToken" contract.