Skip to main content

Each Transmuter takes one synthetic debt asset (alAsset) and is associated with one AlchemistV3 instance used for redemptions.

Variables

StakingPosition

A struct that describes a tranche of deposited synthetic debt assets which have an eventual claim to underlying.

amount
startBlock
maturationBlock

TransmuterInititializationParams

State set by params at creation-time of the transmuter to initially configure it.

syntheticToken
timeToTransmute
transmutationFee
exitFee
protocolFeeReceiver

Constants

Immutable variables used as helpers or for informational purposes.

BPS
FIXED_POINT_SCALAR
  • Description - A multiplier that is used to be able to do fixed point math, since solidity does not natively handle decimals. Like ERC20 tokens which typically use 18 decimals, it expresses 1 as 1e18. Anything less is a fraction of 1.
  • Type - uint256
  • Used By
  • Updated By - NONE - immutable variable
BLOCK_SCALING_FACTOR
version
  • Description - Constant expressing Alchemix version. Not used for anything in the contract.
  • Type - string
  • Updated By - NONE - immutable variable
  • Read By - version()

Public State

State that is available and can be read from outside of the contract.

Uint256

depositCap
totalLocked
totalActiveLocked

Addresses

pendingAdmin
alchemist
admin
  • Description - The current admin address. Set to msg.sender on deployment. Only this address can call functions guarded by the onlyAdmin modifier.
  • Type - address
  • Used By
  • Updated By
  • Read By - admin()
  • Notified By - AdminUpdated(address admin)

Private State

Internal state of the contract. In most cases cannot be read from outside of the contract. In some cases certain aspects can be read using specific functions. (See ReadingState)

_positions
_stakingGraph
_nonce
_countsTowardCap

Functions

User Actions

Functions that can be called by external accounts which influence the state or balance of the Transmuter.

createRedemption(uint256 syntheticDepositAmount, address recipient)
  • Description - Creates a time-locked redemption staked position that linearly vests over timeToTransmute blocks.

    Validates the deposit amount and capacity against both depositCap (using totalActiveLocked) and alchemist.totalSyntheticsIssued() (using totalLocked). Transfers the syntheticDepositAmount of alAsset from the function caller. Records a new StakingPosition from block.number to block.number + timeToTransmute. Updates the staking graph with the per-block redemption rate contributed by this position, adding it to the existing global rate so that redemptions for all positions can be served correctly. Mints a new position token to recipient, increments both totalLocked and totalActiveLocked, and marks the position as counting toward the deposit cap.

    • @param syntheticDepositAmount - amount of syntheticToken deposited in this staking position, to be locked until transmutation is finished or early exit is executed.
    • @param recipient - the address that will own the minted redemption position NFT.
  • Visibility Specifier - external
  • State Mutability Specifier - nonpayable
  • Returns - none
  • Emits
  • Reverts
    • DepositZeroAmount() - if syntheticDepositAmount == 0
    • IllegalArgument() - if recipient is the zero address
    • DepositCapReached() - if totalActiveLocked + syntheticDepositAmount exceeds depositCap, or if totalLocked + syntheticDepositAmount exceeds alchemist.totalSyntheticsIssued(). The latter ensures that more deposits are not accepted than there is debt to service them.
claimRedemption(uint256 id)
  • Description - Settles and closes the redemption for the staked position identified by id, paying out the vested portion in yield tokens and returning any unvested synthetics minus fees applied.

    Validates the position exists and is not being claimed in its creation block. Computes the vested vs. unvested split using block-based linear vesting. Verifies ownership and burns the position token. Calculates bad debt from Alchemist state and scales down vested payout if necessary. First uses yield from prior repayments to reduce redemptions, then redeems the rest from the Alchemist (calls alchemist.redeem()). Applies the transmutation fee to vested yield, and an exit fee to synthetics returned (unvested debt). If the staked position was not fully transmuted (vested) then the staking graph is updated to remove the remaining per-block rate. Transfers yield and synthetic payouts/fees, burns the transmuted synthetics, reduces totalSyntheticsIssued (calls alchemist.reduceSyntheticsIssued()), decrements totalLocked, removes the position from totalActiveLocked if it still counts toward the cap, and deletes the position. Informs the alchemist of its yieldToken quantity (calls alchemist.setTransmuterTokenBalance()).

    • @param id - the id of the staked position to claim and close
  • Visibility Specifier - external
  • State Mutability Specifier - nonpayable
  • Returns - (uint256 claimYield, uint256 feeYield, uint256 syntheticReturned, uint256 syntheticFee) - the amount of yield tokens sent to the claimant, the yield fee sent to the protocol, the amount of synthetic tokens returned to the claimant, and the synthetic exit fee sent to the protocol.
  • Emits
  • Reverts
    • PositionNotFound() - if no position exists for id
    • PrematureClaim() - if claiming in the same block the position was opened
    • CallerNotOwner() - if the message sender does not own the position
acceptAdmin()
  • Description - Can only be called by the current pendingAdmin. Used to accept the admin role.
  • Visibility Specifier - external
  • State Mutability Specifier - nonpayable
  • Returns - none
  • Emits
  • Reverts
    • IllegalState() - if pendingAdmin is the zero address (no pending transfer)
    • Unauthorized() - if msg.sender is not the current pendingAdmin
pokeMatured(uint256 id)
  • Description - Removes a fully matured position from the totalActiveLocked count, freeing up deposit cap space without requiring the position owner to claim. Can be called by anyone.

    Checks that the position exists, is fully matured (current block >= maturation block), and hasn't already been poked. Sets _countsTowardCap[id] to false and decrements totalActiveLocked by the position's amount.
    • @param id - the id of the matured position to poke
  • Visibility Specifier - external
  • State Mutability Specifier - nonpayable
  • Returns - none
  • Emits
  • Reverts
    • PositionNotFound() - if no position exists for id
    • PositionNotMatured(uint256 id, uint256 maturationBlock, uint256 currentBlock) - if the position has not yet fully matured
    • PositionAlreadyPoked(uint256 id) - if the position has already been poked

Admin Actions

Functions guarded by the onlyAdmin modifier.

setPendingAdmin(address value)
  • Description - Sets the pending admin. First part of a two-step process to change the admin. The second step is the pendingAdmin accepting the role by calling acceptAdmin.
  • Visibility Specifier - external
  • State Mutability Specifier - nonpayable
  • Returns - none
  • Emits
  • Reverts
    • IllegalArgument() - if msg.sender is not the current admin
setAlchemist(address value)
  • Description - Sets the address of the AlchemistV3 contract that will be used to redeem against for this Transmuter.
  • Visibility Specifier - external
  • State Mutability Specifier - nonpayable
  • Returns - none
  • Emits
  • Reverts
    • IllegalArgument() - if msg.sender is not the current admin
setDepositCap(uint256 cap)
  • Description - Sets the deposit cap variable, or maximum amount of synthetics that can be staked in the transmuter at any one time.
  • Visibility Specifier - external
  • State Mutability Specifier - nonpayable
  • Returns - none
  • Emits
  • Reverts
    • IllegalArgument() - if msg.sender is not the current admin
    • IllegalArgument() - if cap exceeds type(int256).max
setTransmutationFee(uint256 fee)
  • Description - Sets the fee as a percentage in BPS for transmutation.
  • Visibility Specifier - external
  • State Mutability Specifier - nonpayable
  • Returns - none
  • Emits
  • Reverts
    • IllegalArgument() - if msg.sender is not the current admin
    • IllegalArgument() - if fee exceeds BPS (> 100%)
setExitFee(uint256 fee)
  • Description - Sets the fee as a percentage in BPS for early exits from positions staked for transmutation.
  • Visibility Specifier - external
  • State Mutability Specifier - nonpayable
  • Returns - none
  • Emits
  • Reverts
    • IllegalArgument() - if msg.sender is not the current admin
    • IllegalArgument() - if fee exceeds BPS (> 100%)
setTransmutationTime(uint256 time)
  • Description - Sets the duration of time it takes for new staked positions of synthetic assets to be transmuted in blocks.
  • Visibility Specifier - external
  • State Mutability Specifier - nonpayable
  • Returns - none
  • Emits
  • Reverts
    • IllegalArgument() - if msg.sender is not the current admin
    • IllegalArgument() - if time is 0
    • IllegalArgument() - if time exceeds type(int256).max
setProtocolFeeReceiver(address value)
  • Description - Sets the address that wil recieve fees from the Transmuter.
  • Visibility Specifier - external
  • State Mutability Specifier - nonpayable
  • Returns - none
  • Emits
  • Reverts
    • IllegalArgument() — if msg.sender is not the current admin
    • IllegalArgument() — if value is the zero address

Internal Operations

Functions that are cannot be called by other contracts or EOAs. Used only as helpers for performing internal logic.

_updateStakingGraph(int256 amount, uint256 blocks)
  • Description - Updates the staking graph with a new redemption schedule starting at the current block.

    Delegates to _stakingGraph.addStake(amount, block.number, blocks). Positive amount values add per-block redemption weight, negative values remove it. The change applies for the amount of passed in blocks.

    • @param amount - scaled redemption amount to apply (scaled by BLOCK_SCALING_FACTOR)
    • @param blocks - number of blocks over which the amount should apply
  • Visibility Specifier - private
  • State Mutability Specifier - nonpayable
  • Returns - none
  • Emits - none
  • Reverts - none
_checkArgument(bool expression)
  • Description - Validates a boolean condition intended to check arguments.
    • @param expression - the boolean expression to validate
  • Visibility Specifier - internal
  • State Mutability Specifier - pure
  • Returns - none
  • Emits - none
  • Reverts - IllegalArgument() - if the expression evaluates to false
_checkState(bool expression)
  • Description - Validates a boolean condition intended to check state.
    • @param expression - the boolean expression to validate
  • Visibility Specifier - internal
  • State Mutability Specifier - pure
  • Returns - none
  • Emits - none
  • Reverts - IllegalState() if the expression evaluates to false

Reading State

Reads derived, calculated, or internal state. For getters of public variables see the Variable section.

tokenURI(uint256 id)
  • Description - Gets the token URI for a Transmuter NFT token with a specfic id.
  • Visibility Specifier - public
  • State Mutability Specifier - view
  • Returns - string memory - the URI of the Transmuter NFT with the passed ID
  • Emits - none
  • Reverts - none
getPosition(uint256 id)
  • Description - Gets the StakingPosition identified by id.
  • Visibility Specifier - external
  • State Mutability Specifier - view
  • Returns - StakingPosition memory
  • Emits - none
  • Reverts - none
queryGraph(uint256 startBlock, uint256 endBlock)
  • Description - Allows callers to see how much is scheduled to be redeemed between two blocks numbers.

    Queries the staking graph to calculate the total redemption amount that is scheduled to be applied for all staked positions between two block numbers by delegating to _stakingGraph.queryStake(startBlock, endBlock). If the query does not find an amount for that block span then it returns 0. Otherwise, it uses FixedPointMath.mulDivUp to scale the queried amount back down by BLOCK_SCALING_FACTOR to restore to token units and returns the result.

    • @param startBlock - block number at which to start the query range
    • @param endBlock - block number at which to end the query range
  • Visibility Specifier - external
  • State Mutability Specifier - view
  • Returns - uint256 scheduledAmountToBeRedeemed - total expected redemption amount of scheduled redemptions between the start and end blocks in token units.
  • Emits - none
  • Reverts - none

Events

  • AdminUpdated(address admin) - Emitted when the admin address is updated.
  • PendingAdminUpdated(address pendingAdmin) - Emitted when the pending admin is updated.
  • AlchemistUpdated(address alchemist) - Emitted when the associated alchemist is updated.
  • PositionCreated(address indexed creator, uint256 amountStaked, uint256 nftId) - Emitted when a position is created.
  • PositionClaimed(address indexed claimer, uint256 amountClaimed, uint256 amountUnclaimed) - Emitted when a position is claimed.
  • GraphSizeUpdated(uint256 size) - Defined in the interface but not currently emitted by any function in the contract.
  • DepositCapUpdated(uint256 cap) - Emitted when the deposit cap is updated.
  • TransmutationTimeUpdated(uint256 time) - Emitted when the transmutation time is updated.
  • TransmutationFeeUpdated(uint256 fee) - Emitted when the transmutation fee is updated.
  • ExitFeeUpdated(uint256 fee) - Emitted when the early exit fee is updated.
  • ProtocolFeeReceiverUpdated(address receiver) - Emitted when the fee receiver is updated.
  • PositionPoked(uint256 indexed id, uint256 amountRemovedFromCap) - Emitted when a fully matured position is poked, removing its amount from the active deposit cap count.

Errors

  • DepositZeroAmount() - Reverts when attempting to create a redemption with a zero deposit amount.
  • DepositCapReached() - Reverts when a deposit would push totalActiveLocked above depositCap, or totalLocked above alchemist.totalSyntheticsIssued().
  • PositionNotFound() - Reverts when referencing a position ID that does not exist.
  • PrematureClaim() - Reverts when attempting to claim a position in the same block it was created.
  • CallerNotOwner() - Reverts when the caller does not own the position NFT they are trying to claim.
  • PositionNotMatured(uint256 id, uint256 maturationBlock, uint256 currentBlock) - Reverts when attempting to poke a position that has not yet fully matured.
  • PositionAlreadyPoked(uint256 id) - Reverts when attempting to poke a position that has already been poked.
  • IllegalArgument() - Reverts when a function argument fails a validation check via _checkArgument(). Used across admin setter functions.
  • IllegalState() - Reverts when a state precondition fails via _checkState(). Used in acceptAdmin() to verify a pending admin exists.
  • Unauthorized() - Reverts when msg.sender is not authorized. Used in acceptAdmin() when the caller is not the pendingAdmin.