Unit ID
ID4UieUlggOkdHtiWQZ0a6lr2Hl+Ef9IhSzEJH1RI7Y=
Received
26.05.2023 12:47:21
Confirmation delay (full node)
23 minutes 7 seconds
Confirmation delay (light node)
26 minutes 42 seconds
Messages
Definition
Definition: [ "autonomous agent", { "doc_url": "https://oswap.io/oswap-token-arb.json", "getters": "{ }", "init": "{ $reversed = params.reversed; $token_aa = params.oswap_token_aa; $v2_aa = params.oswap_v2_aa; $v2_params = definition[$v2_aa][1].params; $x_asset = $v2_params.x_asset; $y_asset = $v2_params.y_asset; $get_token_param = ($name, $default) => { $value = var[$token_aa][$name]; exists($value) ? $value : $default }; $get_v2_param = ($name, $default) => { $value = var[$v2_aa][$name]; exists($value) ? $value : (exists($v2_params[$name]) ? $v2_params[$name] : $default) }; $get_shifts = () => { $mid_price = $get_v2_param('mid_price', 0); // price of x_asset in terms of y_asset if ($mid_price){ $alpha = $get_v2_param('alpha', 0.5); $beta = 1 - $alpha; $gamma = $get_v2_param('price_deviation', 0); $lp_shares = var[$v2_aa]['lp_shares']; $s_curve = $lp_shares.linear * $lp_shares.coef; $x0 = $s_curve / $mid_price^$beta / $gamma; $y0 = $x0 * $mid_price; } // else{ // $x0 = 0; // $y0 = 0; // } {x0: $x0, y0: $y0} }; $get_denom = ($balances, $l_balances, $shifts, $pxy, $beta) => { $leverages = [2, 5, 10, 20, 50, 100]; // account for leveraged positions $L_sums = {x: 0}; foreach($leverages, 6, $L => { $L_sums.x = $L_sums.x + ($L - 1) * ($l_balances[$L||'x'].balance + $l_balances[-$L||'x'].balance / $pxy); }); $denom = $beta * ($balances.x + $shifts.x0) - $L_sums.x; // log({denom: $denom, sum: $L_sums.x, share: $L_sums.x/$denom}); require($denom > 0, "negative denom " || $denom); $denom }; $get_available_balance = ($asset) => balance[$asset] - ($asset == 'base' ? 10000 : 0); $scale_amounts_down_if_necessary = ($amounts, $x_balance, $y_balance) => { if ($amounts.x > $x_balance AND $amounts.y > $y_balance){ $x_factor = $x_balance/$amounts.x; $y_factor = $y_balance/$amounts.y; if ($x_factor >= $y_factor){ $amounts.x = $x_balance; $amounts.y = floor($x_factor * $amounts.y); } else { $amounts.y = $y_balance; $amounts.x = floor($y_factor * $amounts.x); } log('scaled down to', $amounts); } }; }", "messages": { "cases": [ { "if": "{ trigger.data.arb}", "init": "{ $share = trigger.data.share OTHERWISE 1; // for incomplete arb $precalculated = trigger.data.amount AND trigger.data.from; if (!$precalculated) { $token_fee = $get_token_param('swap_fee', 0.003); $v2_fee = $get_v2_param('swap_fee', 0.003); $token_state = var[$token_aa]['state']; $p1 = $token_aa#7.$get_price(); $p1x = $reversed ? 1/$p1 : $p1; $balances = var[$v2_aa]['balances']; $l_balances = var[$v2_aa]['leveraged_balances']; $shifts = $get_shifts(); $alpha = $get_v2_param('alpha', 0.5); $beta = 1 - $alpha; $p2 = $alpha/$beta * ($balances.y + $shifts.y0) / ($balances.x + $shifts.x0); $p2_oswap = $reversed ? 1/$p2 : $p2; $denom1 = ($token_state.s0 - $token_state.supply)/2; $denom2 = $get_denom($balances, $l_balances, $shifts, $p2, $beta); $Lambda = $get_v2_param('pool_leverage', 1); $x_balance = $get_available_balance($x_asset); $y_balance = $get_available_balance($y_asset); $amounts = {x: 0, y: 0}; // profitable to buy x on v2 pool and sell on token AA if ($p2 * (1 + $v2_fee) < $p1x * (1 - $token_fee)){ $p2_plus_fee = $p2 * (1 + $v2_fee); $p1x_minus_fee = $p1x * (1 - $token_fee); $amounts.x = floor(($p1x_minus_fee - $p2_plus_fee)/$p1x_minus_fee / (1/$denom2 + 1/$denom1)); $amounts.y = floor($p1x_minus_fee * $amounts.x); // overestimate $scale_amounts_down_if_necessary($amounts, $x_balance, $y_balance); $final_p = $p2 * (1 + $amounts.x/$denom2 * $share); // log({p1: $p1, p2: $p2, p1_minus_fee: $p1_minus_fee, p2_plus_fee: $p2_plus_fee, final_p: $final_p, denom2: $denom2, amounts: $amounts}); if ($amounts.y <= $y_balance){ $from = 'v2y'; $asset = $y_asset; $amount = $amounts.y; $address = $v2_aa; $data = { final_price: $final_p, hops: [ { // next oswap in the chain address: $token_aa, change_address: this_address, data: {to: this_address}, }, ] }; } else{ $from = 'tokenx'; $asset = $x_asset; $amount = $amounts.x; $address = $token_aa; $data = { hops: [ { address: $v2_aa, data: { final_price: $final_p, } }, { address: this_address } ] }; } } // profitable to buy x on token AA and sell on v2 pool else if ($p2 * (1 - $v2_fee) > $p1x * (1 + $token_fee)){ $p2_minus_fee = $p2 * (1 - $v2_fee); $p1x_plus_fee = $p1x * (1 + $token_fee); $amounts.x = floor(($p2_minus_fee - $p1x_plus_fee)/$p2_minus_fee / (1/$denom2 + 1/$denom1)); $amounts.y = floor($amounts.x * $p2_minus_fee); // overestimate $scale_amounts_down_if_necessary($amounts, $x_balance, $y_balance); $final_pyx = 1/$p2 * (1 + $amounts.x/($denom2 + $beta * $Lambda * $amounts.x) * $share); // log({p1: $p1, p2: $p2, p1_plus_fee: $p1_plus_fee, p2_minus_fee: $p2_minus_fee, final_pyx: $final_pyx, denom2: $denom2, amounts: $amounts}); if ($amounts.x <= $x_balance){ $from = 'v2x'; $asset = $x_asset; $amount = $amounts.x; $address = $v2_aa; $data = { final_price: $final_pyx, hops: [ { // next oswap in the chain address: $token_aa, change_address: this_address, data: {to: this_address}, }, ] }; } else { $from = 'tokeny'; $asset = $y_asset; $amount = $amounts.y; $address = $token_aa; $data = { hops: [ { address: $v2_aa, data: { final_price: $final_pyx, } }, { address: this_address } ] }; } } else bounce("no arb opportunity exists"); } else { // overridden in the request, don't calc $amount = trigger.data.amount; $from = trigger.data.from; if ($from == 'v2y'){ $asset = $y_asset; $address = $v2_aa; $data = { final_price: trigger.data.final_p, hops: [ { // next oswap in the chain address: $token_aa, change_address: this_address, data: {to: this_address}, }, ] }; } else if ($from == 'tokenx'){ $asset = $x_asset; $address = $token_aa; $data = { hops: [ { address: $v2_aa, data: { final_price: trigger.data.final_p, } }, { address: this_address } ] }; } else if ($from == 'v2x'){ $asset = $x_asset; $address = $v2_aa; $data = { final_price: trigger.data.final_pyx, hops: [ { // next oswap in the chain address: $token_aa, change_address: this_address, data: {to: this_address}, }, ] }; } else if ($from == 'tokeny'){ $asset = $y_asset; $address = $token_aa; $data = { hops: [ { address: $v2_aa, data: { final_price: trigger.data.final_pyx, } }, { address: this_address } ] }; } } }", "messages": [ { "app": "payment", "payload": { "asset": "{$asset}", "outputs": [ { "address": "{$address}", "amount": "{ $amount }" } ] } }, { "app": "data", "payload": "{$data}" }, { "app": "state", "state": "{ $arb = { from: $from, avg_price: ($p1x + $p2) / 2, sent: {}, received: {}, }; $arb.sent[$asset] = $amount; var['arb'] = $arb; // log({arb: $arb}); response['sent_amount'] = $amount; if ($from == 'v2y') response['message'] = 'will arb by buying X from v2 and selling to token'; else if ($from == 'tokenx') response['message'] = 'will arb by selling X to token and buying from v2'; else if ($from == 'v2x') response['message'] = 'will arb by selling X to v2 and buying from token'; else if ($from == 'tokeny') response['message'] = 'will arb by buying X from token and selling to v2'; }" } ] }, { "if": "{ $received_x = trigger.output[[asset=$x_asset]]; $received_y = trigger.output[[asset=$y_asset]]; $arb = var['arb']; ($received_x > 0 OR $received_y > 0) AND (trigger.address == $token_aa OR trigger.address == $v2_aa) AND $arb }", "init": "{ $from_token = $arb.from == 'tokenx' OR $arb.from == 'tokeny'; require(!($from_token AND trigger.address == $token_aa), 'change from token AA?'); }", "messages": [ { "app": "state", "state": "{ $arb.received[$x_asset] = $arb.received[$x_asset] + $received_x; $arb.received[$y_asset] = $arb.received[$y_asset] + $received_y; $change = !$from_token AND trigger.address == $v2_aa; if ($change){ var['arb'] = $arb; response['message'] = 'received the change from v2'; // log('received the change from v2', $received_x, $received_y); return; } // log('received proceeds', $received_x, $received_y); $sent = $arb.sent[$y_asset] + $arb.sent[$x_asset] * $arb.avg_price; $received = $arb.received[$y_asset] + $arb.received[$x_asset] * $arb.avg_price; $profit_in_y = $received - $sent; $profit_in_x = $profit_in_y / $arb.avg_price; $profit = $reversed ? $profit_in_x : $profit_in_y; // in GBYTE require($profit > 0, "unprofitable " || $arb.from || ": " || $received || " < " || $sent); response['profit'] = $profit; // in GBYTE var['arb'] = false; }" } ] }, { "if": "{ trigger.data.withdraw AND trigger.data.asset AND trigger.address == params.owner }", "init": "{ if (trigger.data.asset == 'x') $asset = $x_asset; else if (trigger.data.asset == 'y') $asset = $y_asset; else $asset = trigger.data.asset; }", "messages": [ { "app": "payment", "payload": { "asset": "{$asset}", "outputs": [ { "address": "{params.owner}", "amount": "{ trigger.data.amount OTHERWISE '' }" } ] } } ] }, { "if": "{ trigger.output[[asset=$x_asset]] > 0 OR trigger.output[[asset=$y_asset]] > 0 }", "messages": [ { "app": "state", "state": "{ response['message'] = 'added'; }" } ] } ] } } ]
Technical information
Fees:
11,416 bytes
(451 headers, 10965 payload)
Level:10224116
Witnessed level:10224105
Main chain index:9855827
Latest included mc index:9855826
Status:stable/confirmed/final