Bonder Contract
Handles bonding of OP20 assets and LP tokens for discounted SLOHM.
Storage
// Bond info per user
bondPayout: AddressMemoryMap // SLOHM owed
bondVesting: AddressMemoryMap // Blocks remaining
bondLastBlock: AddressMemoryMap // Last interaction
// Global
totalDebt: StoredU256 // Outstanding unvested SLOHM
bcv: StoredU256 // Bond Control Variable
vestingBlocks: StoredU256 // Default: 720 blocks
lpCaps: AddressMemoryMap // Max bondable per LP
Key Methods
bond(asset, amount, maxPrice)
function bond(asset, amount, maxPrice): void {
// Verify asset is approved
require(treasury.isApproved(asset));
// Check LP cap if applicable
if (isLP(asset)) {
require(lpBonded[asset] + amount <= lpCaps[asset]);
}
// Pull asset to treasury
asset.transferFrom(sender, treasury, amount);
// Calculate value and discount
const value = isLP(asset) ? calculateRFV(asset, amount) : getAssetValue(asset, amount);
const price = value × (1 + debtRatio × BCV);
require(price <= maxPrice, "Slippage");
// Calculate and record payout
const payout = value / price;
bonds[sender].payout += payout;
bonds[sender].vesting = vestingBlocks;
totalDebt += payout;
}
claim()
function claim(): void {
// Calculate vested amount
const elapsed = block.number - bond.lastBlock;
const percentVested = elapsed / bond.vesting;
const payout = bond.payout × percentVested;
// Mint vested SLOHM
Treasury.mintForBond(sender, payout);
// Update records
bond.payout -= payout;
totalDebt -= payout;
}
RFV Calculation
function calculateRFV(lp, amount): u256 {
const (reserve0, reserve1) = pool.getReserves();
const totalLP = lp.totalSupply();
// RFV = 2 × sqrt(reserve0 × reserve1) × (amount / totalLP)
return 2 × sqrt(reserve0 × reserve1) × amount / totalLP;
}
View Functions
pendingPayout(user)- Total SLOHM owedclaimable(user)- Vested SLOHM availablebondPrice(asset)- Current bond price