Base stTBY

Overview

The StTBYBase contract serves as a base contract to handle the mechanics of the Staked USD (stTBY) token. It operates with a unique mechanism that uses a shares system to calculate user balances based on the total amount of USD controlled by the protocol.

State Variables

  • _shares: A mapping to track the amount of shares held by each address. The balances in stTBY are dynamic and depend on the total USD controlled by the protocol and the shares held by an account.

  • _allowances: A mapping to track the amount of stTBY tokens that an address is allowed to spend on behalf of another address.

  • _totalShares: Stores the total amount of shares issued.

  • _totalUsd: Stores the total amount of USD controlled by the protocol.

Events

  • TransferShares: Emitted when a share transfer is executed from one account to another.

  • SharesBurnt: Emitted when shares are burnt. Reports the amount of stTBY before and after burning along with the burnt share amount.

  • Deposit: Emitted when a user deposits into the contract.

Functions

View and Pure Functions

  • name(): Returns the name of the token, "Staked USD".

  • symbol(): Returns the token symbol, "stTBY".

  • decimals(): Returns the number of decimals for the token, which is 18.

  • totalSupply(): Returns the total supply of the token, equivalent to the total amount of USD controlled by the protocol.

  • getTotalUsd(): Returns the total amount of USD controlled by the protocol.

  • balanceOf(address _account): Returns the balance of stTBY tokens held by _account.

  • allowance(address _owner, address _spender): Returns the amount of stTBY tokens _spender can spend on behalf of _owner.

  • getTotalShares(): Returns the total number of shares in existence.

  • sharesOf(address _account): Returns the number of shares owned by _account.

  • getSharesByUsd(uint256 _usdAmount): Returns the number of shares corresponding to _usdAmount of USD.

  • getUsdByShares: Given a number of shares (_sharesAmount), it calculates the equivalent in USD based on the total shares and total USD in the system. This function could be used to determine the value of a share in terms of USD.

  • transferSharesFrom: Similar to transferShares but it transfers from a specified address (_sender) to another address (_recipient).

  • _getTotalUsd: A view function that returns the total amount of USD in the system. It seems this value is held in a state variable _totalUsd.

  • _setTotalUsd: An internal function to set the value of _totalUsd.

  • _transfer: An internal function that handles the logic for transferring tokens. This function seems to be related to some rebasing mechanism as it translates the token amount to a shares amount.

  • _approve: Used for ERC20-style approval mechanism, where one address can approve another to spend on its behalf.

  • _spendAllowance: Updates an address's allowance based on spent amount.

  • _getTotalShares & _sharesOf: Respectively return the total amount of shares in existence and the amount of shares owned by a specific address.

  • _transferShares: Logic for transferring shares from one address to another.

  • _mintShares: Creates new shares and assigns them to a recipient. Important to note is the comment suggesting that this doesn't increase the token total supply.

  • _burnShares: Destroys a certain number of shares from an address's holdings.

  • _emitTransferEvents: Emits Transfer and TransferShares events after a transfer operation.

State Changing Functions

  • transfer(address _recipient, uint256 _amount): Transfers _amount of stTBY tokens from the message sender to _recipient. Emits Transfer and TransferShares events.

  • approve(address _spender, uint256 _amount): Sets _amount as the allowance of _spender over the caller's tokens. Emits an Approval event.

  • transferFrom(address _sender, address _recipient, uint256 _amount): Transfers _amount of stTBY tokens from _sender to _recipient using the allowance mechanism. Emits Transfer, TransferShares, and Approval events.

  • transferShares: Allows the caller to transfer a specified number of shares (_sharesAmount) to another address (_recipient). The equivalent USD value of the transferred shares is also calculated.

  • increaseAllowance(address _spender, uint256 _addedValue): Increases the allowance granted to _spender by the caller by _addedValue. Emits an Approval event.

  • decreaseAllowance(address _spender, uint256 _subtractedValue): Decreases the allowance granted to _spender by the caller by _subtractedValue. Emits an Approval event.

Mechanics

The contract uses a concept of shares to determine how much stUSD a user has. Each user's balance is computed based on the shares they hold relative to the total shares of the contract.

The formula to compute the balance for a user is:

_balance = _shares[user] * _getTotalUsd() / _getTotalShares()

This mechanism allows the contract to manage dynamic balances and calculate user's token balances based on their shares and the total amount of USD controlled by the protocol.

Considerations

  1. Dynamic Balancing: The unique mechanism of using shares ensures that stUSD balances remain dynamic. The actual USD balance can be computed on the fly based on the shares held by an account.

  2. Transfer Mechanism: The contract emits both Transfer (standard ERC20 event) and TransferShares events on token transfer, ensuring transparency on how many shares correspond to the transferred tokens.

  3. Pausing: The contract can be paused which would prevent transfers. This can be a useful feature during emergencies.

  4. Allowance Management: The contract offers both traditional approve and allowance modification methods (increaseAllowance, decreaseAllowance) to overcome potential issues with the ERC20 approve race condition.

Last updated