Unit ID
z3n+W8o15pGEbkQZzYRg2c7uqLOGkXw6VINP3x5B8po=
Received
18.01.2023 16:29:01
Confirmation delay (full node)
3 minutes 16 seconds
Confirmation delay (light node)
4 minutes 27 seconds
Messages
Definition
Definition: [ "autonomous agent", { "doc_url": "https://pyth.ooo/perpetual.json", "getters": "{ $trade_merge_period = 1; // seconds $get_param = ($name, $default) => { $value = var[$name]; exists($value) ? $value : (exists(params[$name]) ? params[$name] : $default) }; $get_swap_fee = () => $get_param('swap_fee', 0.003); $get_arb_profit_tax = () => $get_param('arb_profit_tax', 0.9); $get_adjustment_period = () => $get_param('adjustment_period', 3 * 24 * 3600); // 3 days $get_presale_period = () => $get_param('presale_period', 1 * 24 * 3600); // 14 days $get_auction_price_halving_period = () => $get_param('auction_price_halving_period', 3 * 24 * 3600); // 3 days $get_token_share_threshold = () => $get_param('token_share_threshold', 0.1); // 10% $get_min_s0_share = () => $get_param('min_s0_share', 0.01); // 1% $pow2 = $x => $x*$x; $adjust_prices = ($asset, $asset_info, $state) => { if ($state.asset0 == $asset) return; $elapsed = timestamp - $asset_info.last_ts; $asset_info.last_ts = timestamp; if ($asset_info.presale AND $asset_info.preipo){ $target_price = $asset_info.last_auction_price; } else{ $price_aa = $asset_info.price_aa; if (!$price_aa) return; $target_price = $price_aa#3.$get_target_price(); if (typeof($target_price) != 'number' OR $target_price < 0) return; } if ($asset_info.presale){ if ( $asset_info.presale_amount AND ( timestamp >= $asset_info.creation_ts + $get_presale_period() OR $asset_info.presale_amount > $get_token_share_threshold() * $state.reserve // we can exceed max_tokens OR $asset_info.preipo AND $asset_info.presale_amount / $target_price >= $asset_info.max_tokens ) ){ // add the reserve and launch trading delete($asset_info, 'presale'); $asset_info.initial_price = $target_price; $asset_info.supply = floor($asset_info.presale_amount / $target_price); $asset_info.a = $pow2($target_price / $state.coef) * $state.reserve/$asset_info.presale_amount; $new_reserve = $state.reserve + $asset_info.presale_amount; $state.coef = $state.coef * sqrt($new_reserve/$state.reserve); $state.reserve = $new_reserve; } return; } $r = $state.reserve; $c = $state.coef; $s = $asset_info.supply; $a = $asset_info.a; $p = $c*$c * $a * $s / $r; $s0 = $state.s0; if (!$s) return; $full_delta_p = $target_price - $p; $adjustment_period = $get_adjustment_period(); $delta_p = $elapsed >= $adjustment_period ? $full_delta_p : $elapsed/$adjustment_period*$full_delta_p; // $delta_a = $a * $delta_p/$p; // >= -$a // $asset_info.a = $asset_info.a + $delta_a; // stays positive // $state.coef = $c / sqrt(1 + $delta_a * $pow2($s * $c / $r)); $new_c = $c * sqrt(1 - $s * $r * $delta_p / ($r*$r - $a * $pow2($c * $s))); require(($new_c - $c) * $delta_p <= 0, "c should change opposite to p"); $new_a = ($p + $delta_p) * $r / $new_c/$new_c / $s; require(($new_a - $a) * $delta_p >= 0, "a should change as p"); $asset_info.a = $new_a; $state.coef = $new_c; // apply drift that slowly depreciates p and moves the wealth to s0 holders if ($asset_info.drift_rate){ $relative_price_drift = $elapsed/360/24/3600 * $asset_info.drift_rate; if ($relative_price_drift < 1){ $asset_info.a = $asset_info.a * (1 - $relative_price_drift); $state.a0 = $state.a0 + $pow2($s/$s0) * $asset_info.a * $relative_price_drift; } } // keeping s0 share above some minimum $a0 = $state.a0; $c1 = $state.coef; $s0_share = $a0 * $pow2($s0 * $c1 / $r); $min_s0_share = $get_min_s0_share(); if ($s0_share < $min_s0_share){ $new_a0 = ($pow2($r/$c1/$s0) - $a0) / (1/$min_s0_share - 1); $new_c2 = $r/$s0 * sqrt($min_s0_share/$new_a0); require($new_a0 > $a0, "a0 should grow"); require($new_c2 < $c, "c should fall"); $state.a0 = $new_a0; $state.coef = $new_c; } }; $get_auction_price = ($asset) => { $state = var['state']; $asset_info = var['asset_'||$asset]; require($asset_info, "no such asset"); require($asset_info.preipo, "not a pre-IPO"); $asset_info.initial_auction_price / 2^((timestamp - $asset_info.creation_ts)/$get_auction_price_halving_period()) }; $get_price = ($asset, $bWithPriceAdjustment) => { $state = var['state']; $bAsset0 = $state.asset0 == $asset; $asset_info = var['asset_'||$asset]; require($asset_info, "no such asset"); if ($bWithPriceAdjustment) $adjust_prices($asset, $asset_info, $state); $r = $state.reserve; $c = $state.coef; $s = $bAsset0 ? $state.s0 : $asset_info.supply; $a = $bAsset0 ? $state.a0 : $asset_info.a; $p = $c*$c * $a * $s / $r; $p }; $get_exchange_result_by_state = ($tokens, $delta_r, $asset, $asset_info, $state, $trigger_initial_address) => { require($tokens > 0 AND $delta_r == 0 OR $tokens == 0 AND $delta_r > 0, "invalid input"); $op = $tokens ? 'sell' : 'buy'; $bAsset0 = $state.asset0 == $asset; $r = $state.reserve; $c = $state.coef; $s = $bAsset0 ? $state.s0 : $asset_info.supply; $a = $bAsset0 ? $state.a0 : $asset_info.a; $p = $s ? $c*$c * $a * $s / $r : 0; log('p = ', $p); $key = 'last_'||$op; $last_trade = $bAsset0 ? $state[$key] : $asset_info[$key]; $bMerge = (timestamp <= $last_trade.ts + $trade_merge_period AND $trigger_initial_address == $last_trade.address); $recent_tax = $bMerge ? $last_trade.tax : 0; $recent_delta_s = $bMerge ? $last_trade.delta_s : 0; $initial_p = $bMerge ? ($tokens ? max($p, $last_trade.initial_p) : min($p, $last_trade.initial_p)) : $p; $swap_fee_rate = $get_swap_fee(); $arb_profit_tax_rate = $get_arb_profit_tax(); $get_new_s = ($new_r, $fee_rate) => sqrt($s*$s + ($new_r*$new_r - $r*$r)/$c/$c/$a * (1 - $fee_rate)); $get_new_r = ($new_s, $fee_rate) => sqrt($r*$r + ($new_s*$new_s - $s*$s)*$c*$c*$a * (1 - $fee_rate)); if ($tokens) { // selling tokens $delta_s = -$tokens; $new_s = $s - $tokens; $new_r1 = $get_new_r($new_s, $swap_fee_rate); $new_p1 = $c*$c * $a * $new_s / $new_r1; $arb_profit_tax = $arb_profit_tax_rate * ($initial_p - $new_p1) * ($tokens - $recent_delta_s) / 2 - $recent_tax; $full_fee_rate = $swap_fee_rate + $arb_profit_tax/($r - $new_r1); require($full_fee_rate < 1, "fee would exceed 100%"); $new_r = ceil($get_new_r($new_s, $full_fee_rate)); require($new_r <= $r, "r would increase to "||$new_r); $swap_fee = $swap_fee_rate * ($r - $new_r); $state.a0 = $bAsset0 ? ($state.a0 * $s*$s + ($new_r*$new_r - $r*$r)/$c/$c)/$new_s/$new_s : $state.a0 + $full_fee_rate * $a * ($s*$s - $new_s*$new_s) / $state.s0 / $state.s0; // $new_r = $net_new_r + $swap_fee; } else { // buying tokens $new_r = $r + $delta_r; $swap_fee = $swap_fee_rate * $delta_r; $new_s1 = $get_new_s($new_r, $swap_fee_rate); log('new_s1 = ', $new_s1); $new_p1 = $c*$c * $a * $new_s1 / $new_r; log('new_p1 = ', $new_p1); $arb_profit_tax = $arb_profit_tax_rate * ($new_p1 - $initial_p) * ($new_s1 - $s + $recent_delta_s) / 2 - $recent_tax; $full_fee_rate = $swap_fee_rate + $arb_profit_tax/$delta_r; require($full_fee_rate < 1, "fee would exceed 100%"); $new_s = floor($get_new_s($new_r, $full_fee_rate)); log('new_s = ', $new_s); $delta_s = $new_s - $s; require($delta_s >= 0, "s would decrease by "||$delta_s); $state.a0 = $bAsset0 ? ($state.a0 * $s*$s + ($new_r*$new_r - $r*$r)/$c/$c)/$new_s/$new_s : $state.a0 + $full_fee_rate * ($new_r*$new_r - $r*$r)/$c/$c/$state.s0/$state.s0; } require($state.a0 > 0, "a0 would become "||$state.a0); $state.reserve = $new_r; if ($bAsset0){ require($state.a0 >= $a, "a0 should grow"); $state.s0 = $new_s; } else $asset_info.supply = $new_s; $new_p = $c*$c * $a * $new_s / $new_r; // fix log('new_p = ', $new_p); // if ($tokens) // $arb_profit_tax = $arb_profit_tax_rate * abs(($new_p - $p) * ($new_s - $s) / 2); $total_fee = $swap_fee + $arb_profit_tax; if ($tokens){ $payout = $r - $new_r; $fee_percent = $total_fee / ($r - $new_r) * 100; } else $fee_percent = $total_fee / $delta_r * 100; if ($bAsset0){ $state[$key].delta_s = ($bMerge ? $last_trade.delta_s : 0) + $delta_s; $state[$key].initial_p = $initial_p; $state[$key].tax = $arb_profit_tax; $state[$key].ts = timestamp; $state[$key].address = $trigger_initial_address; } else { $asset_info[$key].delta_s = ($bMerge ? $last_trade.delta_s : 0) + $delta_s; $asset_info[$key].initial_p = $initial_p; $asset_info[$key].tax = $arb_profit_tax; $asset_info[$key].ts = timestamp; $asset_info[$key].address = $trigger_initial_address; } { payout: $payout, delta_s: $delta_s, old_reserve: $r, new_reserve: $new_r, delta_reserve: $new_r - $r, old_price: $p, new_price: $new_p, swap_fee: $swap_fee, arb_profit_tax: $arb_profit_tax, total_fee: $total_fee, fee_percent: $fee_percent, } }; $get_exchange_result = ($asset, $tokens, $delta_r) => { $state = var['state']; if ($asset != $state.asset0){ $asset_info = var['asset_'||$asset]; require($asset_info, "no such asset"); $adjust_prices($asset, $asset_info, $state); } $get_exchange_result_by_state($tokens, $delta_r, $asset, $asset_info, $state, 'ADDRESS') }; }", "init": "{ $reserve_asset = params.reserve_asset; $aa2aa_bytes = 2000; // reserve $min_contribution = ($reserve_asset == 'base') ? 99999 : 0; $network_fee = ($reserve_asset == 'base') ? 1000 : 0; $state = var['state']; // tokens $asset = trigger.data.asset; if ($asset AND $asset != $state.asset0){ $asset_info = var['asset_'||$asset]; require($asset_info, "no such asset"); $adjust_prices($asset, $asset_info, $state); } if (trigger.data.to AND !is_valid_address(trigger.data.to)) bounce("bad to address"); $to = trigger.data.to OTHERWISE trigger.address; $staking_base_aa = 'DKQFPFCZZFVGACHK5AW5GQ5NOHPNDBLG'; }", "messages": { "cases": [ { "if": "{ trigger.data.define AND !$state }", "init": "{ $params = {aa: this_address}; if (params.challenging_period) $params.challenging_period = params.challenging_period; if (params.max_term) $params.max_term = params.max_term; if (params.min_term) $params.min_term = params.min_term; if (params.decay_factor) $params.decay_factor = params.decay_factor; $staking_aa = [ 'autonomous agent', { base_aa: $staking_base_aa, params: $params } ]; $staking_aa_address = chash160($staking_aa); }", "messages": [ { "app": "asset", "payload": { "is_private": false, "is_transferrable": true, "auto_destroy": false, "fixed_denominations": false, "issued_by_definer_only": true, "cosigned_by_definer": false, "spender_attested": false } }, { "app": "definition", "payload": { "definition": "{$staking_aa}" } }, { "app": "payment", "payload": { "asset": "base", "outputs": [ { "address": "{ $staking_aa_address }", "amount": 1000 } ] } }, { "app": "state", "state": "{ var['staking_aa'] = $staking_aa_address; var['state'] = {asset0: response_unit, a0: 1, s0: 0, reserve: 0, coef: 1}; response['asset'] = response_unit; }" } ] }, { "if": "{ trigger.address == var['staking_aa'] AND trigger.data.name }", "init": "{ $name = trigger.data.name; $value = trigger.data.value; if ($name == 'add_price_aa'){ require($value == 'yes', "can't remove asset"); require(trigger.data.price_aa, "no price_aa"); } else if ($name == 'change_price_aa' OR $name == 'change_drift_rate') require($asset, "no asset"); else if ($name == 'add_preipo'){ require($value == 'yes', "can't remove preipo"); require(trigger.data.symbol, "no symbol"); require(trigger.data.initial_auction_price, "no initial_auction_price"); require(trigger.data.max_tokens, "no max_tokens"); } $bAddNewAsset = ($name == 'add_price_aa' OR $name == 'add_preipo'); }", "messages": [ { "if": "{$bAddNewAsset}", "app": "asset", "payload": { "is_private": false, "is_transferrable": true, "auto_destroy": false, "fixed_denominations": false, "issued_by_definer_only": true, "cosigned_by_definer": false, "spender_attested": false } }, { "if": "{$bAddNewAsset}", "app": "payment", "payload": { "asset": "base", "outputs": [ { "address": "{trigger.address}", "amount": 1000 } ] } }, { "app": "state", "state": "{ if ($bAddNewAsset){ response['asset'] = response_unit; $a_info = { // start a presale // supply: 0, // a: 1, last_ts: timestamp, presale: true, presale_amount: 0, creation_ts: timestamp, }; if ($name == 'add_price_aa') $a_info.price_aa = trigger.data.price_aa; else { $a_info.preipo = true; $a_info.symbol = trigger.data.symbol; $a_info.initial_auction_price = trigger.data.initial_auction_price; $a_info.last_auction_price = trigger.data.initial_auction_price; $a_info.max_tokens = trigger.data.max_tokens; } var['asset_'||response_unit] = $a_info; } else if ($name == 'change_price_aa' OR $name == 'change_drift_rate'){ $asset_info[$name == 'change_price_aa' ? 'price_aa' : 'drift_rate'] = $value; var['asset_'||$asset] = $asset_info; var['state'] = $state; // we adjusted prices since we had asset in trigger.data } else var[$name] = $value; }" } ] }, { "if": "{ $state AND $asset AND trigger.data.presale AND trigger.output[[asset=$reserve_asset]] > $min_contribution }", "init": "{ require($asset_info.presale, "already launched"); // require($asset_info.creation_ts >= timestamp, "already launched"); }", "messages": [ { "app": "state", "state": "{ var['contribution_'||trigger.address||'_'||$asset] += trigger.output[[asset=$reserve_asset]]; $asset_info.presale_amount = $asset_info.presale_amount + trigger.output[[asset=$reserve_asset]]; if ($asset_info.preipo) $asset_info.last_auction_price = $asset_info.initial_auction_price / 2^((timestamp - $asset_info.creation_ts)/$get_auction_price_halving_period()); var['asset_'||$asset] = $asset_info; }" } ] }, { "if": "{ $state AND $asset AND trigger.data.claim }", "init": "{ require(!$asset_info.presale, "not launched yet"); $contribution = var['contribution_'||trigger.address||'_'||$asset]; require($contribution, "you had no contribution or already paid"); }", "messages": [ { "app": "payment", "payload": { "asset": "{$asset}", "outputs": [ { "address": "{$to}", "amount": "{ floor($contribution / $asset_info.initial_price) }" } ] } }, { "app": "state", "state": "{ var['contribution_'||trigger.address||'_'||$asset] = false; var['asset_'||$asset] = $asset_info; // modified if we finished the presale or the price moved var['state'] = $state; }" } ] }, { "if": "{ $state AND $asset AND (trigger.output[[asset=$reserve_asset]] > $min_contribution OR trigger.output[[asset=$asset]] > 0) }", "init": "{ $tokens = trigger.output[[asset=$asset]]; if ($tokens){ require(trigger.output[[asset=$reserve_asset]] <= $min_contribution, "don't send the reserve when redeeming tokens"); } $to_aa = $to != trigger.address AND is_aa($to); $full_network_fee = $network_fee + ($reserve_asset == 'base' ? ($to_aa ? $aa2aa_bytes : 0) : 0); $reserve_asset_amount = $tokens ? 0 : trigger.output[[asset=$reserve_asset]] - $full_network_fee; // subtract a fee to compensate for network fees $res = $get_exchange_result_by_state($tokens, $reserve_asset_amount, $asset, $asset_info, $state, trigger.initial_address); response['price'] = $res.new_price; response['swap_fee'] = $res.swap_fee; response['arb_profit_tax'] = $res.arb_profit_tax; response['total_fee'] = $res.total_fee; if ($res.payout AND $res.payout < 0) bounce("unexpected payout < 0"); if ($res.payout AND trigger.data.min_reserve_tokens AND $res.payout < trigger.data.min_reserve_tokens) bounce("payout would be only " || $res.payout); if (trigger.data.max_fee_percent AND $res.fee_percent > trigger.data.max_fee_percent) bounce("fee would be " || $res.fee_percent || '%'); }", "messages": [ { "if": "{$res.delta_s > 0}", "app": "payment", "payload": { "asset": "{$asset}", "outputs": [ { "address": "{$to}", "amount": "{ $res.delta_s }" } ] } }, { "app": "payment", "payload": { "asset": "{$reserve_asset}", "outputs": [ { "address": "{$to}", "amount": "{$res.payout}", "if": "{$res.payout}" }, { "address": "{$to}", "amount": "{$aa2aa_bytes}", "if": "{ $reserve_asset == 'base' AND $to_aa}" } ] } }, { "if": "{ $reserve_asset != 'base' AND $to_aa }", "app": "payment", "payload": { "asset": "base", "outputs": [ { "address": "{$to}", "amount": "{$aa2aa_bytes}" } ] } }, { "if": "{ $to_aa }", "app": "data", "payload": { "to": "{trigger.address}" } }, { "app": "state", "state": "{ if ($asset != $state.asset0) var['asset_'||$asset] = $asset_info; var['state'] = $state; response['fee%'] = round($res.fee_percent, 4) || '%'; }" } ] } ] } } ]
Technical information
Fees:
17,411 bytes
(452 headers, 16959 payload)
Level:2954325
Witnessed level:2954316
Main chain index:2929564
Latest included mc index:2929563
Status:stable/confirmed/final