Unit ID
IYjG/GdxwjGfJXH3cGnQIQq48piSN2zrmUqUFb95fJU=
Received
21.12.2021 00:35:47
Confirmation delay (full node)
1 minute 54 seconds
Confirmation delay (light node)
3 minutes 3 seconds
Messages
Definition
Definition: [ "autonomous agent", { "getters": "{ $get_leverages = () => [2, 5, 10, 20, 50, 100]; $singularity_threshold = 0.1; // X, Y through P: // without LP leverage (Lambda) $get_final_xy = ($X, $Y, $P, $final_P, $X0, $Y0, $pool_props, $inverted) => { require($final_P >= $P, "not selling Y"); log('get_final_xy', $X, $Y, $P, $final_P, $X0, $Y0); $a = $inverted ? $pool_props.beta : $pool_props.alpha; // alpha $b = 1 - $a; // beta $final_X = ($X + $X0) * ($P/$final_P)^$b - $X0; $final_Y = $b/$a * $final_P * ($final_X + $X0) - $Y0; $deltaX = $X - $final_X; require($final_X >= 0, "bad final_X " || $final_X); require($final_Y >= 0, "bad final_Y " || $final_Y); require($deltaX >= 0, "bad deltaX " || $deltaX); { X: round($final_X), Y: round($final_Y), } }; // along x means keeping x fully leveraged (y underleveraged) $get_final_xy_along_x = ($X, $Y, $P, $final_P, $pool_props, $inverted) => { $a = $inverted ? $pool_props.beta : $pool_props.alpha; // alpha $b = 1 - $a; // beta $final_X = $X * ($P/$final_P)^($b*$pool_props.Lambda); $final_Y = $b/$a * $final_P * $final_X; { X: round($final_X), Y: round($final_Y), } }; // along y means keeping y fully leveraged (x underleveraged) $get_final_xy_along_y = ($X, $Y, $P, $final_P, $pool_props, $inverted) => { $a = $inverted ? $pool_props.beta : $pool_props.alpha; // alpha $b = 1 - $a; // beta $final_Y = $Y * ($final_P/$P)^($a*$pool_props.Lambda); $final_X = $a/$b * $final_Y / $final_P; { X: round($final_X), Y: round($final_Y), } }; $add_net_balance_without_changing_price = ($balances, $side, $amount, $Lambda) => { require($Lambda > 1, "Lambda must be > 1"); $opposite = $side == 'x' ? 'y' : 'x'; $side_n = $side || 'n'; $opposite_n = $opposite || 'n'; $Xn = $balances[$side_n]; $Yn = $balances[$opposite_n]; $X = $balances[$side]; $Y = $balances[$opposite]; $underleveraged = $Xn > ceil($X/$Lambda); $delta_Xn = $amount; // $delta_Yn = 0; // the price doesn't change as X and Y grow proportionally if (!$underleveraged){ // Y is underleveraged, increase Y proportionally while keeping Yn intact $full_delta_Y = $Y * $delta_Xn/$Xn; if ($Y + $full_delta_Y > $Yn * $Lambda){ // would overshoot and make Y overleveraged $ratio = $Yn * $Lambda / $Y - 1; $delta_X = round($ratio * $X); $delta_Y = round($ratio * $Y); } else{ $delta_X = round($delta_Xn * $Lambda); $delta_Y = round($full_delta_Y); } } else{ $delta_X = 0; // only net X gets increased $delta_Y = 0; } $balances[$side_n] = $balances[$side_n] + $delta_Xn; // $balances[$opposite_n] = $balances[$opposite_n] + $delta_Yn; $balances[$side] = $balances[$side] + $delta_X; $balances[$opposite] = $balances[$opposite] + $delta_Y; }; $pow = ($precomputed, $power) => { require($precomputed[$power], "no precomputed power " || $power); $precomputed[$power] }; $precompute = $v => { $pre = {}; $pre['2'] = $v * $v; $pre['5'] = $pre['2'] * $pre['2'] * $v; $pre['10'] = $pre['5'] * $pre['5']; $pre['20'] = $pre['10'] * $pre['10']; $pre['50'] = $pre['20'] * $pre['20'] * $pre['10']; $pre['100'] = $pre['50'] * $pre['50']; $pre }; $update_leveraged_balances = ($x, $y, $final_x, $final_y, $x0, $y0, $l_balances, $alpha, $inverted) => { $beta = 1 - $alpha; $p = $alpha/$beta * ($y + $y0) / ($x + $x0); // price of x in terms of y $P = $inverted ? 1/$p : $p; // price of X in terms of Y $final_p = $alpha/$beta * ($final_y + $y0) / ($final_x + $x0); $final_P = $inverted ? 1/$final_p : $final_p; // $P_powers = $precompute($P); // $final_P_powers = $precompute($final_P); $ratio = $final_P/$P; $ratio_powers = $precompute($ratio); $totals = { delta_XL: 0, // (L>0) X added to the L-pools (bought from the swap pool) minus (L<0) new X borrowed by the L-pools (sent to the swap pool for buying Y) delta_YL: 0, // (L>0) Y added to the L-pools (bought from the swap pool) minus (L<0) new Y borrowed by the L-pools (sent to the swap pool for buying X) XL_denom: 0, YL_denom: 0, }; // if inverted, XL corresponds to y, YL to x foreach($get_leverages(), 6, ($L) => { $allyL = $inverted ? -$L : $L; $balance = $l_balances[$allyL||'x'].balance; $obalance = $l_balances[-$allyL||'x'].balance; if (!$balance AND !$obalance) return; // $PL1 = $pow($P_powers, $L) / $P; // $final_PL1 = $pow($final_P_powers, $L) / $final_P; $ratio_L1 = $pow($ratio_powers, $L) / $ratio; $debt_ratio = ($L-1)/$L; if ($balance) { $delta_XL_balance = round($balance * ($ratio_L1 - 1)); $new_XL_balance = $balance + $delta_XL_balance; $l_balances[$allyL||'x'].balance = $new_XL_balance; $delta_YL_balance = -(($new_XL_balance * $final_P - $balance * $P) * $debt_ratio); // borrowed $totals.delta_XL = $totals.delta_XL + $delta_XL_balance; $totals.delta_YL = $totals.delta_YL + $delta_YL_balance; $totals.XL_denom = $totals.XL_denom + $new_XL_balance * ($L-1); } if ($obalance) { // e.g. L=-2 $delta_YL_obalance = round($obalance * (1/$ratio_L1 - 1)); $new_YL_obalance = $obalance + $delta_YL_obalance; $l_balances[-$allyL||'x'].balance = $new_YL_obalance; $delta_XL_obalance = -(($new_YL_obalance / $final_P - $obalance / $P) * $debt_ratio); // borrowed $totals.delta_YL = $totals.delta_YL + $delta_YL_obalance; $totals.delta_XL = $totals.delta_XL + $delta_XL_obalance; $totals.YL_denom = $totals.YL_denom + $new_YL_obalance * ($L-1); } }); $totals }; $swap = ($balances, $l_balances, $x0, $y0, $y_in, $in_delta_Yn, $final_P, $received_amount_Y, $min_amount_out, $pool_props) => { require(!$in_delta_Yn, "no delta Yn please, this is swap by P"); $alpha = $pool_props.alpha; $beta = $pool_props.beta; $Lambda = $pool_props.Lambda; $xn = $balances.xn; $yn = $balances.yn; $x = $balances.x; $y = $balances.y; if ($y_in){ $inverted = false; $X = $x; $Y = $y; $Xn = $xn; $Yn = $yn; $X0 = $x0; $Y0 = $y0; $a = $alpha; $b = $beta; } else{ // x <-> y swap their roles. Uppercase X, Y, and P refer to invertable values $inverted = true; $X = $y; $Y = $x; $Xn = $yn; $Yn = $xn; $X0 = $y0; $Y0 = $x0; $a = $beta; $b = $alpha; } $P = $a/$b * ($Y + $Y0) / ($X + $X0); // price of X in terms of Y require($final_P > $P, "price should increase, current " || $P || ", target " || $final_P); if ($Lambda > 1){ $underleveraged = $Xn > ceil($X/$Lambda); } if ($Lambda == 1){ $final = $get_final_xy($X, $Y, $P, $final_P, $X0, $Y0, $pool_props, $inverted); $final_X = $final.X; $final_Y = $final.Y; $final_Xn = $final_X; $final_Yn = $final_Y; } else if (!$underleveraged){ // along X $final = $get_final_xy_along_x($X, $Y, $P, $final_P, $pool_props, $inverted); $final_X = $final.X; $final_Y = $final.Y; $final_Xn = round($final_X/$Lambda); $delta_Y = $final_Y - $Y; $delta_Yn = -round($a/($b*$Lambda-1)*$delta_Y); $final_Yn = $Yn + $delta_Yn; } else if ($underleveraged){ $inflection_P = $P * ( $Lambda/($Lambda-1) * ($b + ($a * $Lambda - 1) * $Xn/$X) )^(1/($a*$Lambda-1)); $inflected = $final_P > $inflection_P; // along Y until the inflection point $final_P1 = $inflected ? $inflection_P : $final_P; $final1 = $get_final_xy_along_y($X, $Y, $P, $final_P1, $pool_props, $inverted); $final_X1 = $final1.X; $final_Y1 = $final1.Y; $final_Yn1 = round($final_Y1 / $Lambda); $delta_X1 = $final_X1 - $X; $delta_Xn1 = -round($b/($a*$Lambda-1) * $delta_X1); $final_Xn1 = $Xn + $delta_Xn1; if ($inflected){ // then, along X $final = $get_final_xy_along_x($final_X1, $final_Y1, $final_P1, $final_P, $pool_props, $inverted); $final_X = $final.X; $final_Y = $final.Y; $final_Xn = round($final_X/$Lambda); $delta_Y2 = $final_Y - $final_Y1; $delta_Yn2 = -round($a/($b*$Lambda-1)*$delta_Y2); $final_Yn = $final_Yn1 + $delta_Yn2; require($final_Xn <= $final_Xn1, "Xn didn't decrease"); } else{ $final_X = $final_X1; $final_Y = $final_Y1; $final_Xn = $final_Xn1; $final_Yn = $final_Yn1; } } else bounce("???"); $balances.x = $y_in ? $final_X : $final_Y; $balances.y = $y_in ? $final_Y : $final_X; $balances.xn = $y_in ? $final_Xn : $final_Yn; $balances.yn = $y_in ? $final_Yn : $final_Xn; log("balances after swap", $balances); $final_y = $balances.y; $final_x = $balances.x; // if inverted, XL corresponds to y, YL to x $totals = $update_leveraged_balances($x, $y, $final_x, $final_y, $x0, $y0, $l_balances, $alpha, $inverted); $amount_X = floor(-($final_Xn - $X + $totals.delta_XL)); $amount_Y = ceil($final_Yn - $Yn + $totals.delta_YL); if ($received_amount_Y >= 0) require($received_amount_Y >= $amount_Y, "expected " || $amount_Y || ", received " || $received_amount_Y); require($amount_X >= 0, "to pay " || $amount_X); if ($min_amount_out) require($amount_X >= $min_amount_out, "output amount " || $amount_X || " would be less than the expected minimum " || $min_amount_out); $change = $received_amount_Y - $amount_Y; $denom = 1 - $totals.XL_denom/$b/($final_X+$X0) - $totals.YL_denom/$a/($final_Y+$Y0); log('denom after swap to price:', $denom); require($denom >= $singularity_threshold, "too close to the singularity point, denom="||$denom||", need more liquidity in order to swap this amount"); // arb tax based on price difference require($final_P > $P, "price should have risen but hasn't, old " || $P || ", new " || $final_P); $arb_profit_in_Y = ($final_P - $P) * $amount_X / 2; // in Y $arb_profit_in_X = $arb_profit_in_Y / $final_P; $fee = ceil($arb_profit_in_X * $pool_props.arb_profit_tax + $amount_X * $pool_props.swap_fee); $net_amount_X = $amount_X - $fee; // add the fee to the pool without trading and affecting the price (Lambda>1) or to a separate profit accumulator (Lambda=1) if ($Lambda > 1) $add_net_balance_without_changing_price($balances, $y_in ? 'x' : 'y', $fee, $Lambda); { net_amount_X: $net_amount_X, amount_Y: $amount_Y, fee: $fee, change: $change, // delta_Xn: $final_Xn - $Xn + $fee_delta_Xn, // delta_Yn: $delta_Yn + $fee_delta_Y, // delta_X: $final_X - $X + $fee_delta_X, // delta_Y: $final_Y - $Y + $fee_delta_Y, } }; }", "messages": [ { "app": "state", "state": "{ $A = $swap(); bounce("library only"); }" } ] } ]
Technical information
Fees:
11,570 bytes
(452 headers, 11118 payload)
Level:2537595
Witnessed level:2537587
Main chain index:2515761
Latest included mc index:2515759
Status:stable/confirmed/final