Unit ID
1r2z2XJ/DHKgxqdrb3aXwsaZvzD/Nm+a//HZskBiu+Y=
Received
26.01.2023 13:07:43
Confirmation delay (full node)
1 minute 43 seconds
Confirmation delay (light node)
2 minutes 34 seconds
Messages
Definition
Definition: [ "autonomous agent", { "doc_url": "https://oswap.io/token.json", "getters": "{ $reserve_asset = 'base'; $initial_s0 = 1e13; $min_staking_term = 14; // in days $lib_aa = 'U6TGY7C5SLLIPDDCEDAXHMZV7Y2DN3GK'; $common_ts = 1657843200; // Fri Jul 15 2022 00:00:00 GMT+0000 $year = 31104000; // 360 * 24 * 3600; $max_pools_per_group = 30; $max_groups = 40; $get_param = ($name, $default) => { $value = var[$name]; exists($value) ? $value : $default }; $get_swap_fee = () => $get_param('swap_fee', 0.003); $get_arb_profit_tax = () => $get_param('arb_profit_tax', 0.9); $get_base_rate = () => $get_param('base_rate', 0.3); // rate of appreciation if TVL = base TVL $get_inflation_rate = () => $get_param('inflation_rate', 0.1); $get_stakers_share = () => $get_param('stakers_share', 0.5); // share of emissions that is distributed among stakers $get_base_tvl = () => $get_param('base_tvl', 1e6); // in USD $get_oracle = () => $get_param('oracle', 'WMFLGI2GLAB2MDF2KQAH37VNRRMK7A5N'); $get_challenging_period = () => $get_param('challenging_period', 7200); // 2 hours $get_tvl = () => data_feed[[oracles=$get_oracle(), feed_name='TVL', ifnone=0]]; $get_appreciation_rate = () => $get_base_rate() * $get_tvl() / $get_base_tvl(); $apply_appreciation = ($state) => { ($lib_aa||'')#0.$apply_appreciation($state, $get_appreciation_rate()); }; $get_reserve = ($s) => { $state = var['state'] OTHERWISE {coef: 1, s0: $initial_s0, supply: 0, reserve: 0}; $apply_appreciation($state); ($lib_aa||'')#0.$get_reserve_by_state(exists($s) ? $s : $s, $state); }; $get_tokens = ($r) => { $state = var['state'] OTHERWISE {coef: 1, s0: $initial_s0, supply: 0, reserve: 0}; $apply_appreciation($state); ($lib_aa||'')#0.$get_tokens_by_state(exists($r) ? $r : $state.reserve, $state) }; $get_price = ($s) => { $state = var['state'] OTHERWISE {coef: 1, s0: $initial_s0, supply: 0, reserve: 0}; $apply_appreciation($state); ($lib_aa||'')#0.$get_price_by_state(exists($s) ? $s : $state.supply, $state) }; $get_exchange_result = ($tokens, $delta_r) => { $state = var['state']; $props = { swap_fee: $get_swap_fee(), arb_profit_tax: $get_arb_profit_tax(), }; $apply_appreciation($state); ($lib_aa||'')#0.$get_exchange_result_by_state($tokens, $delta_r, 'ADDRESS', $state, $props) }; $get_vp = ($user_address) => { $user = var['user_' || $user_address]; $user ? $user.normalized_vp * 4^((timestamp - $common_ts)/$year) : 0 }; $get_staking_reward = ($user_address) => { $state = var['state']; $user = var['user_' || $user_address]; $props = { inflation_rate: $get_inflation_rate(), stakers_share: $get_stakers_share(), }; ($lib_aa||'')#0.$distribute_stakers_emissions($state, $user, $props); $user.reward }; $get_lp_reward = ($user_address, $pool_asset, $deposit_aa) => { $state = var['state']; $props = { inflation_rate: $get_inflation_rate(), stakers_share: $get_stakers_share(), }; $full_pool_asset = $pool_asset || ($deposit_aa ? '_'||$deposit_aa : ''); $pool = var['pool_'||$full_pool_asset]; require($pool, "no such pool "||$full_pool_asset); $pool_vps = var['pool_vps_'||$pool.group_key] OTHERWISE {}; $lp_key = 'lp_' || ($deposit_aa OTHERWISE $user_address) || '_' || $pool.asset_key; $lp = var[$lp_key] OTHERWISE {balance: 0, last_pool_emissions: 0, last_distribution_ts: 0, reward: 0}; if ($deposit_aa) $lp.balance = balance[$deposit_aa][$pool_asset]; $total_lp_balance = $deposit_aa ? $lp.balance : var['pool_asset_balance_' || $pool.asset_key]; ($lib_aa||'')#0.$distribute_lp_emissions($state, $lp, $pool, $pool_vps, $total_lp_balance, $props); $lp.reward }; }", "init": "{ $lib = $lib_aa||''; $aa2aa_bytes = 2000; // reserve $min_contribution = ($reserve_asset == 'base') ? 99999 : 0; $network_fee = ($reserve_asset == 'base') ? 1000 : 0; $constants = var['constants'] OTHERWISE {}; // tokens $asset = $constants.asset; $state = var['state'] OTHERWISE { coef: 1, s0: $initial_s0, supply: 0, reserve: 0, last_ts: timestamp, last_buy: { ts: timestamp, delta_s: 0, initial_p: 0, tax: 0, address: '', }, last_sell: { ts: timestamp, delta_s: 0, initial_p: 0, tax: 0, address: '', }, total_normalized_vp: 0, stakers_emissions: 0, lp_emissions: 0, }; if ($asset) $apply_appreciation($state); if (trigger.data.to AND !is_valid_address(trigger.data.to)) bounce("bad to address"); $to = trigger.data.to OTHERWISE trigger.address; // $user_address = (trigger.data.stake OR trigger.data.unstake OR trigger.data.withdraw_staking_reward OR trigger.data.withdraw_lp_reward OR trigger.data.withdraw OR trigger.data.vote_shares OR trigger.data.vote_whitelist OR trigger.data.vote_blacklist OR trigger.data.vote_value) ? trigger.address : $to; $user_address = (trigger.data.deposit OR trigger.data.stake) ? $to : trigger.address; if (trigger.data.pool_asset) require(asset[trigger.data.pool_asset].exists, "bad pool asset"); if (trigger.data.deposit_aa) require(is_aa(trigger.data.deposit_aa), "deposit AA is not an AA"); $user = var['user_' || $user_address] OTHERWISE { balance: 0, reward: 0, normalized_vp: 0, last_stakers_emissions: 0, expiry_ts: 0, }; $props = { inflation_rate: $get_inflation_rate(), stakers_share: $get_stakers_share(), swap_fee: $get_swap_fee(), arb_profit_tax: $get_arb_profit_tax(), }; $challenging_period = $get_challenging_period(); $initial_sale_pool_base_aa = 'B7KGP2YMMLCLDVVCT3Z3GSTGLBRGORW5'; }", "messages": { "cases": [ { "if": "{ trigger.data.define AND !$asset }", "init": "{ $initial_sale_pool_aa = [ 'autonomous agent', { base_aa: $initial_sale_pool_base_aa, params: { token_aa: this_address, reserve_asset: $reserve_asset, buy_freeze_period: 0, launch_date: '2023-01-26T19:06:20Z' } } ]; $constants.initial_sale_pool_address = chash160($initial_sale_pool_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": "{$initial_sale_pool_aa}" } }, { "app": "state", "state": "{ response['initial_sale_pool_address'] = $constants.initial_sale_pool_address; response['asset'] = response_unit; $constants.asset = response_unit; var['constants'] = $constants; }" } ] }, { "if": "{ $asset AND (trigger.output[[asset=$asset]] > 0 OR trigger.data.stake_reward) AND ($to == trigger.address OR $to == trigger.initial_address) AND trigger.data.stake AND trigger.data.term AND trigger.data.group_key AND trigger.data.percentages }", "init": "{ $term = trigger.data.term; // in days $four_years = 4 * 360; require($term >= $min_staking_term AND is_integer($term) AND $term <= $four_years, "invalid term"); $new_expiry_ts = timestamp + $term * 24 * 3600; require($new_expiry_ts >= $user.expiry_ts, "the new term should expire after " || timestamp_to_string($user.expiry_ts)); $group_key = trigger.data.group_key; $votes = var['votes_'||$user_address] OTHERWISE {}; $group_vps = var['group_vps'] OTHERWISE {}; $pool_vps = var['pool_vps_'||$group_key] OTHERWISE {}; }", "messages": [ { "app": "state", "state": "{ $lib#0.$distribute_stakers_emissions($state, $user, $props); $accumulated_reward = trigger.data.stake_reward AND $to == trigger.address ? floor($user.reward) : 0; $amount = trigger.output[[asset=$asset]] + $accumulated_reward; $new_balance = $user.balance + $amount; // require($amount > 0, "nothing to stake"); $final_voting_power = $new_balance / 256; $normalized_voting_power = $final_voting_power * 4^($term/360 + (timestamp - $common_ts)/$year); // vp decays 4 times every year $user.expiry_ts = $new_expiry_ts; $user.balance = $new_balance; if ($accumulated_reward) $user.reward = $user.reward - $accumulated_reward; $delta_normalized_vp = $normalized_voting_power - $user.normalized_vp; $user.normalized_vp = $normalized_voting_power; $state.total_normalized_vp = $state.total_normalized_vp + $delta_normalized_vp; $lib#1.$distribute_new_vp($votes, $pool_vps, $delta_normalized_vp, trigger.data.percentages); $group_vps[$group_key] = $group_vps[$group_key] + $delta_normalized_vp; $group_vps.total = $group_vps.total + $delta_normalized_vp; var['votes_'||$user_address] = $votes; var['pool_vps_'||$group_key] = $pool_vps; var['group_vps'] = $group_vps; var['user_'||$user_address] = $user; var['state'] = $state; }" } ] }, { "if": "{ $asset AND trigger.data.unstake AND trigger.data.group_key }", "init": "{ require(timestamp >= $user.expiry_ts, "you can unstake only after " || timestamp_to_string($user.expiry_ts)); $group_key = trigger.data.group_key; $votes = var['votes_'||$user_address]; require($votes, "you have no votes"); // require(!$user.count_voted_props, "please remove your votes first"); $group_vps = var['group_vps'] OTHERWISE {}; $pool_vps = var['pool_vps_'||$group_key] OTHERWISE {}; }", "messages": [ { "app": "payment", "payload": { "asset": "{$asset}", "outputs": [ { "address": "{$to}", "amount": "{ $user.balance }" } ] } }, { "app": "state", "state": "{ $removed_normalized_vp = $user.normalized_vp; $lib#1.$remove_votes($votes, $pool_vps); $pool_vps.total = $pool_vps.total - $removed_normalized_vp; $group_vps[$group_key] = $group_vps[$group_key] - $removed_normalized_vp; $group_vps.total = $group_vps.total - $removed_normalized_vp; var['user_'||$user_address] = false; var['votes_'||$user_address] = false; var['pool_vps_'||$group_key] = $pool_vps; var['group_vps'] = $group_vps; $state.total_normalized_vp = $state.total_normalized_vp - $removed_normalized_vp; var['state'] = $state; }" } ] }, { "if": "{ $asset AND trigger.data.withdraw_staking_reward }", "init": "{ $lib#0.$distribute_stakers_emissions($state, $user, $props); $reward = floor($user.reward); // fractional part is lost // require($reward > 0, "no reward yet"); }", "messages": [ { "app": "payment", "payload": { "asset": "{$asset}", "outputs": [ { "address": "{$to}", "amount": "{ $reward }" } ] } }, { "app": "state", "state": "{ $user.reward = 0; var['user_'||$user_address] = $user; var['state'] = $state; }" } ] }, { "if": "{trigger.data.deposit OR trigger.data.pool_asset AND (trigger.data.withdraw OR trigger.data.withdraw_lp_reward)}", "init": "{ if (trigger.data.deposit) { $bDeposit = true; $pool_asset = trigger.output[[asset!='base']].asset; require($pool_asset != 'ambiguous' AND $pool_asset != 'none' AND $pool_asset != $asset, "invalid pool asset"); $full_pool_asset = $pool_asset; $deposit_amount = trigger.output[[asset!='base']]; $delta_balance = $deposit_amount; } else if (trigger.data.pool_asset) { $pool_asset = trigger.data.pool_asset; $deposit_aa = trigger.data.deposit_aa; // optional: the tokens are stored on deposit_aa rather than our AA $full_pool_asset = $pool_asset || ($deposit_aa ? '_'||$deposit_aa : ''); if (trigger.data.withdraw){ $bWithdraw = true; require(!$deposit_aa, "can't withdraw to deposit AA"); } else if (trigger.data.withdraw_lp_reward) { // if a user's share of LP tokens increases and they don't withdraw for a long time, they can get an unfairly large share for the earlier period when their share was small. This would also lead to excessive emission (by a factor of 2 in the worst case if there are 2 LPs). To prevent this, any third party can trigger the AA with "for" param and record the reward according to the current share. $for_user_address = trigger.data.for; // if not a valid address, $lp will be zeros } $bWithdrawLpReward = !$for_user_address; // otherwise we only update the $lp using distribute_lp_emissions() but don't send anything } $pool = var['pool_'||$full_pool_asset]; require($pool, "unknown asset"); $lp_key = 'lp_' || ($deposit_aa OTHERWISE $for_user_address OTHERWISE $user_address) || '_' || $pool.asset_key; $lp = var[$lp_key] OTHERWISE {balance: 0, last_pool_emissions: 0, last_distribution_ts: 0, reward: 0}; if ($deposit_aa) $lp.balance = balance[$deposit_aa][$pool_asset]; if (trigger.data.pool_asset){ require($lp.balance > 0, "you have no balance in this pool asset"); if ($bWithdraw){ $withdrawal_amount = trigger.data.amount OTHERWISE $lp.balance; require(is_integer($withdrawal_amount) AND $withdrawal_amount > 0 AND $withdrawal_amount <= $lp.balance, "invalid withdrawal amount"); $delta_balance = -$withdrawal_amount; } } $pool_vps = var['pool_vps_'||$pool.group_key] OTHERWISE {}; $total_lp_balance = $deposit_aa ? $lp.balance : var['pool_asset_balance_' || $pool.asset_key]; $lib#0.$distribute_lp_emissions($state, $lp, $pool, $pool_vps, $total_lp_balance, $props); }", "messages": [ { "if": "{$bWithdraw}", "app": "payment", "payload": { "asset": "{$pool_asset}", "outputs": [ { "address": "{$to}", "amount": "{$withdrawal_amount}" } ] } }, { "if": "{$bWithdrawLpReward}", "app": "payment", "payload": { "asset": "{$asset}", "outputs": [ { "address": "{$deposit_aa OTHERWISE $to}", "amount": "{ floor($lp.reward) }" } ] } }, { "app": "state", "state": "{ if ($bDeposit OR $bWithdraw){ $lp.balance = $lp.balance + $delta_balance; var['pool_asset_balance_' || $pool.asset_key] += $delta_balance; if ($bDeposit) response['deposited'] = $deposit_amount; } if ($bWithdrawLpReward) $lp.reward = 0; var[$lp_key] = $bWithdraw AND $lp.balance == 0 ? false : $lp; var['pool_'||$full_pool_asset] = $pool; var['state'] = $state; }" } ] }, { "if": "{trigger.data.vote_shares AND trigger.data.changes AND trigger.data.group_key1}", "init": "{ $changes = trigger.data.changes; $group_key1 = trigger.data.group_key1; $group_key2 = trigger.data.group_key2; require(is_assoc($changes), "invalid changes object"); $votes = var['votes_'||$user_address] OTHERWISE {}; $group_vps = var['group_vps'] OTHERWISE {}; $pool_vps = {}; $pool_vps[$group_key1] = var['pool_vps_'||$group_key1] OTHERWISE {}; if ($group_key2) $pool_vps[$group_key2] = var['pool_vps_'||$group_key2] OTHERWISE {}; $lib#1.$apply_vote($votes, $pool_vps, $group_key1, $group_key2, $group_vps, $changes); }", "messages": [ { "app": "state", "state": "{ var['votes_'||$user_address] = $votes; var['group_vps'] = $group_vps; var['pool_vps_'||$group_key1] = $pool_vps[$group_key1]; if ($group_key2) var['pool_vps_'||$group_key2] = $pool_vps[$group_key2]; }" } ] }, { "if": "{(trigger.data.vote_whitelist OR trigger.data.vote_blacklist OR trigger.data.vote_neutral) AND trigger.data.pool_asset}", "init": "{ $sign = trigger.data.vote_whitelist ? 1 : (trigger.data.vote_blacklist ? -1 : 0); $pool_asset = trigger.data.pool_asset; $deposit_aa = trigger.data.deposit_aa; $full_pool_asset = $pool_asset || ($deposit_aa ? '_'||$deposit_aa : ''); $wl_votes = var['wl_votes_'||$full_pool_asset] OTHERWISE {vp: 0, flip_ts: 0}; $old_vp = var['user_wl_votes_'||$user_address||'_'||$full_pool_asset]; $new_vp = $user.normalized_vp * $sign; $added_vp = $new_vp - $old_vp; }", "messages": [ { "app": "state", "state": "{ var['user_wl_votes_'||$user_address||'_'||$full_pool_asset] += $added_vp; $new_total_vp = $wl_votes.vp + $added_vp; if ($new_total_vp AND $wl_votes.vp * $new_total_vp <= 0) // flipped the sign $wl_votes.flip_ts = timestamp; $wl_votes.vp = $new_total_vp; var['wl_votes_'||$full_pool_asset] = $wl_votes; // commit if have the majority or stayed unchallenged long enough if (abs($new_total_vp) > $state.total_normalized_vp/2 OR timestamp > $wl_votes.flip_ts + $challenging_period OR $state.total_normalized_vp == 0){ $pool = var['pool_'||$full_pool_asset]; if ($new_total_vp > 0 OR $state.total_normalized_vp == 0){ // add to the whitelist (or re-add) if (!$pool){ // create a new pool var['last_asset_num'] += 1; $last_asset_num = var['last_asset_num']; if ($state.total_normalized_vp == 0 AND $state.supply == 0) require($last_asset_num == 1, "only one asset can be added without voting"); $asset_key = 'a' || $last_asset_num; /* if (trigger.data.group_key){ // indicated the group where to add the new pool $group_key = trigger.data.group_key; $pool_vps = var['pool_vps_'||$group_key]; require($pool_vps, "no such group"); require(length($pool_vps) < 101, "the group is already full"); } else {*/ // add the new pool to the last group, or create a new group if the last one is full $last_group_num = var['last_group_num']; $last_pool_vps = var['pool_vps_g'||$last_group_num]; // +1 adds the 'total' key if (!$last_group_num OR length($last_pool_vps) >= $max_pools_per_group + 1){ // start a new group var['last_group_num'] += 1; $group_num = $last_group_num + 1; require($group_num <= $max_groups, "too many groups"); $pool_vps = {total:0}; } else{ $group_num = $last_group_num; $pool_vps = $last_pool_vps; } $group_key = 'g' || $group_num; // } $pool_vps[$asset_key] = 0; var['pool_vps_'||$group_key] = $pool_vps; $new_pool = { asset_key: $asset_key, group_key: $group_key, last_lp_emissions: $state.lp_emissions, received_emissions: 0, }; response['message'] = 'whitelisted'; } else{ // revive a previously blacklisted pool if ($pool.blacklisted){ $pool.blacklisted = false; $pool.last_lp_emissions = $state.lp_emissions; // skipping all emissions accrued while we were blacklisted response['message'] = 're-whitelisted'; } } } else{ // blacklist if ($pool AND !$pool.blacklisted){ $pool.blacklisted = true; response['message'] = 'blacklisted'; } } var['pool_'||$full_pool_asset] = $new_pool OTHERWISE $pool; /* if (!$old_vp AND $new_vp) // joining the vote on this pool $delta_voted_props = 1; else if ($old_vp AND !$new_vp) // removing one's vote $delta_voted_props = -1; if ($delta_voted_props) { $user.count_voted_props = $user.count_voted_props + $delta_voted_props; var['user_'||$user_address] = $user; } */ } }" } ] }, { "if": "{trigger.data.vote_value AND trigger.data.name}", "init": "{ $name = trigger.data.name; $value = trigger.data.value; if ($name == 'proposal'){ $num = trigger.data.num; require($num, "no proposal number"); $proposal = var['proposal_' || $num]; require($proposal, "no such proposal"); $full_name = $name||$num; } else $full_name = $name; if (exists($value)){ if ($name == 'swap_fee') require($value >= 0 AND $value < 1, "invalid value"); else if ($name == 'arb_profit_tax') require($value >= 0, "invalid value"); else if ($name == 'base_rate') require($value >= 0, "invalid value"); else if ($name == 'inflation_rate') require($value >= 0, "invalid value"); else if ($name == 'stakers_share') require($value >= 0 AND $value <= 1, "invalid value"); else if ($name == 'base_tvl') require($value > 0, "invalid value"); else if ($name == 'oracle') require(is_valid_address($value), "invalid value"); else if ($name == 'challenging_period') require(is_integer($value) AND $value > 0, "invalid value"); else if ($name == 'proposal'){ require($value == 'yes' OR $value == 'no', "invalid value"); require(parse_date($proposal.expiry) > timestamp, "the proposal has expired"); require(!$proposal.result, "the proposal has already been decided upon"); } else bounce("unknown variable"); } $prev_vote = var['user_value_votes_'||$user_address||'_'||$full_name]; $vp = $user.normalized_vp; $leader = var['leader_'||$full_name] OTHERWISE {}; $subtracted_from_leader_vp = ($prev_vote AND exists($leader.value) AND $prev_vote.value == $leader.value AND $value != $prev_vote.value) ? $prev_vote.vp : 0; // removing my vote from the current leader $leader_vp = exists($leader.value) ? var['value_votes_'||$full_name||'_'||$leader.value] - $subtracted_from_leader_vp : 0; if (exists($value)){ $added_vp = $vp - ($prev_vote AND $prev_vote.value == $value ? $prev_vote.vp : 0); $new_vp = var['value_votes_'||$full_name||'_'||$value] + $added_vp; if ((!exists($leader.value) OR $leader.value != $value) AND $new_vp > $leader_vp){ $leader.value = $value; $leader.flip_ts = timestamp; $new_leader_vp = $new_vp; $bLeaderChanged = true; response['new_leader'] = $value; } else $new_leader_vp = $leader_vp; $bProposalJustFinished = $new_leader_vp > $state.total_normalized_vp/2 AND $name == 'proposal' AND !$proposal.result; if ($bProposalJustFinished) $proposal.result = $leader.value; } }", "messages": [ { "if": "{$bProposalJustFinished AND $proposal.result == 'yes'}", "app": "payment", "payload": { "asset": "{$reserve_asset}", "outputs": [ { "address": "{$proposal.recipient}", "amount": "{$proposal.amount}" } ] } }, { "app": "state", "state": "{ if ($prev_vote) var['value_votes_'||$full_name||'_'||$prev_vote.value] -= $prev_vote.vp; if (exists($value)){ var['value_votes_'||$full_name||'_'||$value] += $vp; if ($bLeaderChanged) var['leader_'||$full_name] = $leader; $is_new_value = () => { $current_value = var[$name]; !exists($current_value) OR $current_value != $leader.value }; // commit token params if ($name != 'proposal' AND $is_new_value() AND ($new_leader_vp > $state.total_normalized_vp/2 OR timestamp > $leader.flip_ts + $challenging_period AND $name != 'challenging_period')){ var[$name] = $leader.value; response['committed'] = $leader.value; } // commit proposals if ($bProposalJustFinished){ var['proposal_' || $num] = $proposal; if ($proposal.result == 'yes'){ $lib#0.$subtract_grant($state, $proposal.amount); var['state'] = $state; response['committed'] = 'proposal_' || $num; } } } var['user_value_votes_'||$user_address||'_'||$full_name] = exists($value) ? {value:$value, vp:$vp} : false; /* if (!$prev_vote AND exists($value)) // joining the vote on this prop $delta_voted_props = 1; else if ($prev_vote AND !exists($value)) // removing one's vote $delta_voted_props = -1; if ($delta_voted_props) { $user.count_voted_props = $user.count_voted_props + $delta_voted_props; var['user_'||$user_address] = $user; } */ }" } ] }, { "if": "{ trigger.data.add_proposal }", "init": "{ require(is_valid_address(trigger.data.recipient), "invalid grant recipient address"); require(is_integer(trigger.data.amount) AND trigger.data.amount > 0, "invalid grant amount"); require(unit[trigger.data.unit], "proposal unit not found"); require(trigger.data.expiry, "proposal expiry date not set"); $expiry_ts = parse_date(trigger.data.expiry); require($expiry_ts, "invalid expiry date"); }", "messages": [ { "app": "state", "state": "{ var['count_proposals'] += 1; $num = var['count_proposals']; var['proposal_' || $num] = { recipient: trigger.data.recipient, amount: trigger.data.amount, unit: trigger.data.unit, expiry: trigger.data.expiry, }; }" } ] }, { "if": "{ $asset AND (trigger.output[[asset=$reserve_asset]] > $min_contribution OR trigger.output[[asset=$asset]] > 0) }", "init": "{ require($state.supply OR trigger.address == $constants.initial_sale_pool_address, "only the initial sale pool is allowed to make the first purchase"); $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 = $lib#0.$get_exchange_result_by_state($tokens, $reserve_asset_amount, trigger.initial_address, $state, $props); 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; response['coef_multiplier'] = $res.coef_multiplier; 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": "{ floor($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": "{ $state.supply = $state.supply + $res.delta_s; $state.reserve = $state.reserve + $res.delta_reserve; $state.coef = $state.coef * $res.coef_multiplier; var['state'] = $state; response['fee%'] = round($res.fee_percent, 4) || '%'; }" } ] } ] } } ]
Technical information
Fees:
27,153 bytes
(452 headers, 26701 payload)
Level:2959299
Witnessed level:2959290
Main chain index:2934474
Latest included mc index:2934473
Status:stable/confirmed/final