[
"autonomous agent",
{
"init": "{
if (!trigger.data.feed_name)
bounce('no data feed');
if (trigger.output[[asset!=base]].asset != 'none')
bounce('foreign coins');
$fee = 1000;
$coef = 1.5;
$period_length = 3600;
// $period_length = 3*24*3600;
}",
"messages": {
"cases": [
{
"if": "{trigger.data.feed_value}",
"init": "{$key = sha256(trigger.data.feed_name || '=' || trigger.data.feed_value); // long keys not allowed}",
"messages": {
"cases": [
{
"if": "{
if (trigger.output[[asset=base]] < 1e6)
return false;
$amount = trigger.output[[asset=base]] - $fee;
if (var[$key] == 'committed')
bounce('already committed');
$outcome = trigger.data.outcome otherwise 'yes';
if ($outcome != 'yes' AND $outcome != 'no')
bounce('neither yes nor no');
$bInitialStake = !var[$key];
if ($bInitialStake AND $outcome == 'no')
bounce('initial stake cannot be on No');
if ($bInitialStake)
return true;
// else expect a counterstake
if (timestamp - var[$key || '_countdown_start'] > $period_length)
bounce('challenging period expired');
$current_outcome = var[$key || '_outcome'];
if ($current_outcome == $outcome)
bounce('staking on the current outcome is not allowed');
$stake_on_current_outcome = var[$key || '_total_staked_on_' || $current_outcome] otherwise 0;
$stake_on_proposed_outcome = var[$key || '_total_staked_on_' || $outcome] otherwise 0;
$required_to_challenge = round($coef * $stake_on_current_outcome);
$would_override_current_outcome = ($stake_on_proposed_outcome + $amount >= $required_to_challenge);
if ($would_override_current_outcome)
$excess = $stake_on_proposed_outcome + $amount - $required_to_challenge;
true
}",
"messages": [
{
"if": "{$excess > 0}",
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{trigger.address}",
"amount": "{$excess}"
}
]
}
},
{
"app": "state",
"state": "{
if ($bInitialStake){
var[$key] = 'onreview';
var[$key || '_initial_reporter'] = trigger.address;
}
if ($bInitialStake OR $would_override_current_outcome){
var[$key || '_countdown_start'] = timestamp;
var[$key || '_outcome'] = $outcome;
response['countdown_started'] = true;
response['outcome'] = $outcome;
}
else
response['outcome'] = $current_outcome;
$accepted_amount = $amount - $excess;
var[$key || '_total_staked'] += $accepted_amount;
var[$key || '_total_staked_on_' || $outcome] += $accepted_amount;
var[$key || '_total_staked_on_' || $outcome || '_by_' || trigger.address] += $accepted_amount;
response['staked_on_yes'] = var[$key || '_total_staked_on_yes'] otherwise 0;
response['staked_on_no'] = var[$key || '_total_staked_on_no'] otherwise 0;
response['your_stake'] = var[$key || '_total_staked_on_' || $outcome || '_by_' || trigger.address];
}"
}
]
},
{
"if": "{
if (!trigger.data.commit)
return false;
if (!var[$key])
bounce('unknown feed');
if (var[$key] == 'committed')
bounce('already committed');
if (timestamp - var[$key || '_countdown_start'] <= $period_length)
bounce('challenge period is still running');
$outcome = var[$key || '_outcome'];
// immediately pay to the initial reporter. Other stakers will have to manually request withdrawals
if ($outcome == 'yes'){
$address = var[$key || '_initial_reporter'];
$initial_reporter_stake = var[$key || '_total_staked_on_' || $outcome || '_by_' || $address];
if (!$initial_reporter_stake)
bounce('something went wrong: no initial reporter stake');
$reward = var[trigger.data.feed_name || '_reward'];
$total_winning_stake = var[$key || '_total_staked_on_' || $outcome];
$total_stake = var[$key || '_total_staked'];
$amount = round($initial_reporter_stake / $total_winning_stake * $total_stake);
$full_amount = $amount + $reward;
}
true
}",
"messages": [
{
"if": "{$outcome == 'yes'}",
"app": "data_feed",
"payload": {
"{trigger.data.feed_name}": "{trigger.data.feed_value}"
}
},
{
"if": "{$outcome == 'yes'}",
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$address}",
"amount": "{$full_amount}"
}
]
}
},
{
"app": "state",
"state": "{
var[$key] = 'committed';
if ($outcome == 'yes'){
var[$key || '_paid_out_' || $address] = 1;
var[trigger.data.feed_name || '_reward'] = false;
}
response['message'] = "committed";
}"
}
]
},
{
"if": "{
if (!trigger.data.withdraw)
return false;
if (!var[$key])
bounce('unknown feed');
if (var[$key] != 'committed')
bounce('not committed yet');
$address = trigger.data.address otherwise trigger.address;
if (var[$key || '_paid_out_' || $address])
bounce("you were already paid");
$outcome = var[$key || '_outcome'];
$my_stake = var[$key || '_total_staked_on_' || $outcome || '_by_' || $address];
if (!$my_stake)
bounce("you didn't stake on the winning outcome");
$total_winning_stake = var[$key || '_total_staked_on_' || $outcome];
$total_stake = var[$key || '_total_staked'];
$amount = round($my_stake / $total_winning_stake * $total_stake);
// additional reward might go to the initial reporter if the outcome is positive
if ($outcome == 'yes' AND var[$key || '_initial_reporter'] == $address)
$reward = var[trigger.data.feed_name || '_reward'];
$full_amount = $amount + $reward;
true
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$address}",
"amount": "{$full_amount}"
}
]
}
},
{
"app": "state",
"state": "{
var[$key || '_paid_out_' || $address] = 1;
if ($reward)
var[trigger.data.feed_name || '_reward'] = false;
response['message'] = "paid " || $full_amount || " bytes";
}"
}
]
}
]
}
},
{
"messages": [
{
"app": "state",
"state": "{
var[trigger.data.feed_name || '_reward'] += trigger.output[[asset=base]];
response['message'] = "increased the reward pool by " || trigger.output[[asset=base]] || " bytes";
}"
}
]
}
]
}
}
]