[
"autonomous agent",
{
"bounce_fees": {
"base": 11000
},
"init": "{
$aa_name = "CODAAA"; // Safe Autonomous Agent Forwarding Estate;
$aa_asset_creation_and_issuing = "
O7NYCFUL5XIJTYE3O4MKGMGMTN6ATQAJ"; // could withdraw the dust is calculable;
$DAY = 60 * 60 * 24;
$WEEK = 7 * $DAY;
$YEAR = 364.25 * $DAY;
$TOTAL_CODS_AMOUNT=1e15;
// BONUS RELATED STUFF
$DEBUG = true;
// There is a give away period for people ready to stake their bytes:
$GIVEAWAY_PERIOD = $DEBUG ? 15*60 : 0.5 * $YEAR;
// at the beginning of the give away period the bonus is max:
$MAX_BONUS_P100 = 200;
// then during every day the bonus is reducing:
$DAILY_BONUS_REDUCTION_P100 = 1;
// We need better interest for longer stake: return = 0.7 * ln(period) + 1.5
// Viva robin the hood!, we need to steal the riches to feed the pool: reduction_p100 = 0.04 * ln(balance) - 0.31
// ACCOUNTING RELATED STUFF
// Every given time interest should be computed and paied by each user
$ACCOUNTING_PERIOD = 1 * $YEAR;
// from the pool of unclaim coins, we can allow a percentage per week
$YEARLY_INTEREST_P100_FROM_POOL = 4 / 52; // 4% per year
// load state concerning the CODAA
$temp_next_accounting_time = parse_date(var["next_accounting_time"]) otherwise 0;
$temp_interest_next_accounting = json_parse(var["interest_next_accounting"]) otherwise 0;
$temp_pool_balance = json_parse(var["pool_balance"]) otherwise $TOTAL_CODS_AMOUNT;
// load state concerning the user
$account_name = trigger.data.account_name otherwise bounce ("Please specify an account name");
$user_bytes = json_parse(var[trigger.address||"_"||$account_name||"_bytes"]) otherwise 0;
$user_cods = json_parse(var[trigger.address||"_"||$account_name||"_cods"]) otherwise 0;
$user_stake_start = parse_date(var[trigger.address||"_"||$account_name||"_stake_start"]) otherwise timestamp;
$user_predicted_lock_time = parse_date(var[trigger.address||"_"||$account_name||"_predicted_lock_time"]) otherwise trigger.data.lock_time;
// make weekly accounting? (removing the needed coin reserved to pay interets from the pool)
if ( timestamp > $temp_next_accounting_time )
{
$cods_available_from_pool = round(json_parse(var["pool_balance"]) * $YEARLY_INTEREST_P100_FROM_POOL / 100);
$pool_balance = $temp_pool_balance - $cods_available_from_pool;
$next_accounting_time = $temp_next_accounting_time + $ACCOUNTING_PERIOD;
$interest_next_accounting = 0;
}
else
{
$pool_balance = $temp_pool_balance;
$next_accounting_time = $temp_next_accounting_time;
$interest_next_accounting = $temp_interest_next_accounting;
}
}",
"messages": {
"cases": [
{
"if": "{ !!trigger.data.create}",
"init": "{
}",
"messages": [
{
"app": "asset",
"payload": {
"cap": "{$TOTAL_CODS_AMOUNT}",
"is_private": false,
"is_transferrable": true,
"fixed_denominations": false,
"auto_destroy": false,
"cosigned_by_definer": false,
"issued_by_definer_only": true,
"spender_attested": false
}
},
{
"app": "state",
"state": "{
var["cods_id"] = response_unit;
var["block_until"] = timestamp_to_string(timestamp + $GIVEAWAY_PERIOD);
var["next_accounting_time"] = timestamp_to_string(timestamp + $ACCOUNTING_PERIOD);
var["pool_balance"] = $TOTAL_CODS_AMOUNT;
}"
}
]
},
{
"if": "{ !!trigger.data.claim }",
"init": "{
if (!!$user_bytes or !!$user_cods)
bounce ($account_name||" for the address "||trigger.address||" already exist, use another address or another 'account_name' !");
if (!trigger.data.lock_time)
bounce("Set lock time");
// Amount received to be blocked to receive free coins
$received_bytes = trigger.output[[asset=base]].amount;
// free coin computation
$remaining_time = parse_date(var["block_until"]) - timestamp;
if ($remaining_time<0)
bounce ("Sorry, The free CODs offering is finished !");
$elapsed_time = $GIVEAWAY_PERIOD - $remaining_time;
$elapsed_days = round($elapsed_time/$DAY);
$remaining_days = round($remaining_time/$DAY);
$bonus = $MAX_BONUS_P100 - ($elapsed_days * $DAILY_BONUS_REDUCTION_P100);
$unfair_free_cods = $received_bytes * ($bonus / 100);
// robin hood effect, steal the riches and give to the ... pool, 1Gb = 100% 10Gb = 88%, 72, 56,40,24,8%
$uncorrected_robin_percentage = -0.07 * ln($received_bytes) +2.5;
// if more than 100% bring it back to 100%
$robin_percentage = $uncorrected_robin_percentage>1 ? 1 : $uncorrected_robin_percentage;
$free_cods = round($unfair_free_cods * $robin_percentage);
}",
"messages": [
{
"app": "state",
"state": "{
var["interest_next_accounting"] = $interest_next_accounting + $new_interest;
var["pool_balance"] = $pool_balance - $free_cods;
$key = trigger.address||"_"||$account_name;
var[$key||"_bytes"] = $received_bytes;
var[$key||"_cods"] = $free_cods;
var[$key||"_stake_start"] = $user_stake_start;
var[$key||"_predicted_lock_time"] = $user_predicted_lock_time;
response["message"] = "Your "||$received_bytes||" bytes are safe with us until: "||var["block_until"]||". You will receive "||$free_cods||" free CODs. You still have "||$remaining_days||" days to claim more CODs. Actual bonus is "||$bonus||"% of your bytes.";
}"
}
]
},
{
"if": "{ !!trigger.data.cancel_claim }",
"init": "{
if (!$user_bytes)
bounce ("Nothing to cancel ! are you using the right address ?");
$predicted_interest = $user_cods * (0.7 * ln($user_predicted_lock_time) + 1.5);
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{trigger.address}",
"amount": "{ $user_bytes + trigger.output[[asset=base]].amount - 1000 }"
}
]
}
},
{
"app": "state",
"state": "{
var["interest_next_accounting"] = $interest_next_accounting - $predicted_interest;
var["pool_balance"] = $pool_balance + $user_cods;
var[$key||"_bytes"] = false; // back to user
var[$key||"_cods"] = false; // back to the pool
var[$key||"_stake_start"] = false;
response["message"] = "Your requested your "||$user_bytes||" bytes back. YOu have lost your "||$user_cods||" CODs.";
}"
}
]
},
{
"if": "{ !!trigger.data.get_bytes_back }",
"init": "{
if (!$user_bytes)
bounce ($account_name||" with the address "||trigger.address||" do NOT exist !");
if ( timestamp < parse_date(var["block_until"]))
bounce ("Too early to get your bytes back, except if you ready to loose your CODs, in this case use 'cancel_claim'.");
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{ trigger.address }",
"amount": "{ $user_bytes + trigger.output[[asset=base]].amount - 1000 }"
}
]
}
},
{
"app": "state",
"state": "{
var[trigger.address||"_"||$account_name||"_bytes"] = false;
response["message"] = "Your "||$user_bytes||" bytes have been sent back to you, you have now "||$user_cods||" CODs staking since "||$user_stake_start||".";
}"
}
]
},
{
"if": "{ !!trigger.data.stake }",
"init": "{
if (trigger.output[[asset!=base]].asset != $cods )
bounce ("You can only stake CODs ('"||$cods||"'.");
if (!!$user_cods)
bounce ($account_name||" for the address "||trigger.address||" already exist, use another address or another 'account_name' !");
$received_cods = trigger.output[[asset!=base]].amount;
$new_interest = $received_cods * (0.7 * ln($user_predicted_lock_time) + 1.5); // longer stake => bigger return
}",
"messages": [
{
"app": "state",
"state": "{
var["interest_next_accounting"] = $interest_next_accounting + $new_interest;
$key = trigger.address||"_"||$account_name;
var[$key||"_cods"] = $received_cods;
var[$key||"_stake_start"] = $user_stake_start;
var[$key||"_predicted_lock_time"] = $user_predicted_lock_time;
response["message"] = $received_cods||" CODs in stake until "||timestamp_to_string($user_stake_start + $user_predicted_lock_time)||".";
}"
}
]
},
{
"if": "{ !!trigger.data.unstake }",
"init": "{
if (!$user_cods)
bounce ($account_name||" with the address "||trigger.address||" do NOT exist !");
if (!!$user_bytes)
bounce ("Cannot unstake while having bytes in the system, please use 'get_bytes_back' or 'cancel_claim'!");
$too_early = timestamp < $user_stake_start + $user_predicted_lock_time;
if ( !!$too_early and !trigger.data.use_force )
bounce ("Your defined staking period ends in "||($user_stake_start + $user_predicted_lock_time-timestamp)/24/60/60||" days. To force the unstaking and loose a big part of your interests use 'use_force' !");
// compute interets
$predicted_interest = $user_cods * (0.7 * ln($user_predicted_lock_time) + 1.5);
}",
"messages": [
{
"app": "state",
"state": "{
var["interest_next_accounting"] = $interest_next_accounting - $predicted_interest;
$key = trigger.address||"_"||$account_name;
var[$key||"_cods"] = false;
var[$key||"_stake_start"] = false;
var[$key||"_predicted_lock_time"] = false;
response["message"] = "Your "||$user_cods||" CODs have been sent to you, you have now.";
}"
}
]
},
{
"init": "{
if (!$user_cods)
bounce ($account_name||" with the address "||trigger.address||" do NOT exist !");
$too_early = timestamp < $user_stake_start + $user_predicted_lock_time;
// compute interets
$predicted_interest = $user_cods * (0.7 * ln($user_predicted_lock_time) + 1.5);
}",
"messages": [
{
"app": "state",
"state": "{
var["interest_next_accounting"] = 0;
var["pool_balance"] = $pool_balance + $user_cods;
$key = trigger.address||"_"||$account_name;
var[$key||"_cods"] = $received_cods;
var[$key||"_stake_start"] = $user_stake_start;
var[$key||"_predicted_lock_time"] = $user_predicted_lock_time;
response["message"] = $received_cods||" CODs in stake until "||timestamp_to_string($user_stake_start + $user_predicted_lock_time)||".";
}"
}
]
}
]
}
}
]