When a position is first opened, a trader requires a non-zero amount of premiums in his deposit, indexed by his position id.
mapping(PositionId =>uint256) public PremiumDeposit;
Premiums are computed and paid from this deposit every time a trader adds or reduces a position.
An off-chain bot will continuously monitor positions and close positions that satisfy the following condition:
// Get premiums quoted this block// This will be automatically paid when a trader is interacting with the protocoluint256 premiumQuoted =computePremiums(PositionId); // can force close if deposit is less than the instantaneous premiums owed bool canForceClose = PremiumDeposit[PositionId] < premiumQuoted;
Computing Premiums
A pseudocode for computing premiums is presented below.
functioncomputePremiums( PositionId positionId) publicviewreturns(uint256 premium){ (uint lastPremiumPaymentTime, BorrowedTick[] memory borrowedTicks)=getPositionInfo(PositionId); // get the time-weighted averaged tick between current time and last payment time// The 'distance' between the twat and the borrowed ticks will determine the // multiplierint24 twat =getTimeWeightedAverageTick(block.timestamp - lastPremiumPaymentTime); for(uint i; i<borrowedTicks.length; i++){// the closer the twat to the borrowed tick, the higher the multiplieruint multiplier =getMultiplier(twat, borrowedTicks[i].tick); // get the interest accumulator at the given tickuint interestGrowthInTick =getInterestGrowth(borrowedTicks[i].tick); // since interestGrowth is an accumulator, need to get actually owed interestuint interest = (interestGrowthInTick/borrowedTicks[i].lastInterestGrowth); // scale interest by multiplier interest = interest * multiplier; // add to total premiums for all borrowed ticks premium += interest *toTokenAmounts(borrowedTicks[i].liquidity) }return premium; }functiongetInterestGrowth(int24 tick) publicviewreturns(uint256){ UtilizationGrowth memory growth = UtilizationGrowths[tick];// interest rate per second is proportional to utilization rate, // where the utilization rate is recorded whenever a user provides,withdraws,borrows, or repays// the tickuint percentageIncreaseFromLastGrowth =getInterestRate(growth.lastURate) ** (block.timestamp- growth.lastUpdateTime); // the higher the last recorded utilization rate of the tick, the faster// the rate of growthuint totalAccumulatedGrowthForTick = growth.lastGrowth * percentageIncreaseFromLastGrowth;return totalAccumulatedGrowthTick;}
Since the growth object of a given tick is updated every time an LP provides or withdraws or when a trader borrows and repays, the accumulator will be reflective of all debt originated from that tick.
Interest Rate
The getInterestRate function above is a piecewise function with a pivot rate. Each tick is characterized by its rate function.