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
- Description - The amount of debt tokens deposited and staked.
- Type - uint256
- Used By *
claimRedemption(uint256 id)
startBlock
- Description - Block when the position was opened
- Type - uint256
- Used By -
claimRedemption(uint256 id)
maturationBlock
- Description - Block at which the transmutation will be complete/claimable
- Type - uint256
- Used By -
claimRedemption(uint256 id)
TransmuterInititializationParams
State set by params at creation-time of the transmuter to initially configure it.
syntheticToken
- Description - the contract of the synthetic asset which will be accepted in staking positions
- Type - address
- Used By
- Read By -
syntheticToken()
timeToTransmute
- Description - the time in blocks that it will take to transmuter new staking positions
- Type - uint256
- Used By
- Read By
timeToTransmute()
- Nofified By -
TransmutationTimeUpdated()
transmutationFee
- Description - the fee percentage on transmutation claims. Expressed in BPS.
- Type - uint256
- Used By
- Updated By
- Read By
transmutationFee()
- Nofified By -
TransmutationFeeUpdated()
exitFee
- Description - the fee percentage on transmuter claims for early exits. Expressed in BPS.
- Type - uint256
- Used By
- Updated By
- Read By
exitFee()
- Nofified By -
ExitFeeUpdated()
protocolFeeReceiver
- Description - the address that receives protocol fees from transmutation claims and early exit fees.
- Type - address
- Used By
- Updated By
- Read By
protocolFeeReceiver()
- Notified By -
ProtocolFeeReceiverUpdated()
Constants
Immutable variables used as helpers or for informational purposes.
BPS
- Description - Constant equaling 10_000. Used for any explicit decimal representation. Treats 100% as 10,000; meaning 10% would be expressed as 1000 BPS.
- Type - uint256
- Used By
- Updated By - NONE - immutable variable
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
- Description - A constant set to 1e8. Used as a fixed-point scaling factor when dividing token amounts by block counts, allowing precise ratios to be stored in the staking graph.
- Type - int256
- Used By
- Updated By - NONE - immutable variable
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
- Description - The max number of debt tokens that can be deposited and staked
- Type - uint256
- Used By
- Updated By
- Read By
depositCap()
- Notified By -
DepositCapUpdated(uint256 cap)
totalLocked
- Description - The total amount of synthetic debt tokens currently locked across all staking positions in the transmuter.
- Type - uint256
- Used By
- Updated By
- Read By -
totalLocked()
totalActiveLocked
- Description - The total amount of synthetic debt tokens locked in positions that still count toward the deposit cap. Matured positions can be "poked" via
pokeMatured()to remove them from this count, freeing deposit cap space without requiring the owner to claim. - Type - uint256
- Used By
- Updated By
- Read By -
totalActiveLocked()
Addresses
pendingAdmin
- Description - The address of the pending admin. Part of a two step process where the admin sets a new pendingAdmin, and the pendingAdmin must then accept the role to transition to the actual admin.
- Type - address
- Used By
- Updated By
- Read By
pendingAdmin()
- Notified By -
PendingAdminUpdated(address value)
alchemist
- Description - The AlchemistV3 contract instance used for redemptions.
- Type - IAlchemistV3
- Used By
- Updated By
- Read By
alchemist()
- Notified By -
AlchemistUpdated(address value)
admin
- Description - The current admin address. Set to
msg.senderon deployment. Only this address can call functions guarded by theonlyAdminmodifier. - Type - address
- Used By
onlyAdminacceptAdmin()
- 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
- Description - A mapping of IDs to StakingPositions. Used to track individual staking positions.
- Type -
mapping(uint256 => StakingPosition) - Used By
- Updated By
- Read By -
getPosition(uint256 id)
_stakingGraph
- Description - A graph of transmuter staking positions stored as a Fenwick tree. Tracks the per-block redemption rate across all active positions, enabling efficient range queries for scheduled redemptions.
- Type - StakingGraph.Graph
- Used By
- Updated By
- Read By -
queryGraph(uint256 startBlock, uint256 endBlock)
_nonce
- Description - An incrementing counter used for minting new Transmuter NFT positions so that each has its own unique id.
- Type - uint256
- Used By
- Updated By
- Read By - none
_countsTowardCap
- Description - A mapping tracking whether a position's locked amount still counts toward the deposit cap (
totalActiveLocked). Set to true when a position is created. Set to false when the position is claimed or whenpokeMatured()is called on a fully matured position. - Type -
mapping(uint256 => bool) - Used By
- Updated By
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
timeToTransmuteblocks.
Validates the deposit amount and capacity against bothdepositCap(usingtotalActiveLocked) andalchemist.totalSyntheticsIssued()(usingtotalLocked). Transfers thesyntheticDepositAmountof alAsset from the function caller. Records a newStakingPositionfromblock.numbertoblock.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 torecipient, increments bothtotalLockedandtotalActiveLocked, and marks the position as counting toward the deposit cap.
@param syntheticDepositAmount- amount ofsyntheticTokendeposited 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()- ifsyntheticDepositAmount == 0IllegalArgument()- ifrecipientis the zero addressDepositCapReached()- iftotalActiveLocked + syntheticDepositAmountexceedsdepositCap, or iftotalLocked + syntheticDepositAmountexceedsalchemist.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 (callsalchemist.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, reducestotalSyntheticsIssued(callsalchemist.reduceSyntheticsIssued()), decrementstotalLocked, removes the position fromtotalActiveLockedif it still counts toward the cap, and deletes the position. Informs the alchemist of its yieldToken quantity (callsalchemist.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 foridPrematureClaim()- if claiming in the same block the position was openedCallerNotOwner()- 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()- ifpendingAdminis the zero address (no pending transfer)Unauthorized()- ifmsg.senderis not the currentpendingAdmin
pokeMatured(uint256 id)
- Description - Removes a fully matured position from the
totalActiveLockedcount, 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 decrementstotalActiveLockedby 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 foridPositionNotMatured(uint256 id, uint256 maturationBlock, uint256 currentBlock)- if the position has not yet fully maturedPositionAlreadyPoked(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()- ifmsg.senderis 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()- ifmsg.senderis 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()- ifmsg.senderis not the current adminIllegalArgument()- ifcapexceedstype(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()- ifmsg.senderis not the current adminIllegalArgument()- iffeeexceeds 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()- ifmsg.senderis not the current adminIllegalArgument()- iffeeexceeds 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()- ifmsg.senderis not the current adminIllegalArgument()- iftimeis 0IllegalArgument()- iftimeexceedstype(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()— ifmsg.senderis not the current adminIllegalArgument()— ifvalueis 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). Positiveamountvalues 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 byBLOCK_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 usesFixedPointMath.mulDivUpto scale the queried amount back down byBLOCK_SCALING_FACTORto 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 pushtotalActiveLockedabovedepositCap, ortotalLockedabovealchemist.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 inacceptAdmin()to verify a pending admin exists.