Definition: [
"autonomous agent",
{
"bounce_fees": {
"base": 11000
},
"init": "{
$aa_name = "CODAA"; // Safe Autonomous Agent Forwarding Estate;
$aa_asset_creation_and_issuing = "O7NYCFUL5XIJTYE3O4MKGMGMTN6ATQAJ"; // could withdraw the dust is calculable;
$DANAA = var[$LOPAVAA]["DANAA_last_version"]; // Dynamic Asset Name AA;
$DAY = 60 * 60 * 24;
$WEEK = 7 * $DAY;
$YEAR = 364.25 * $DAY;
// 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
$byte_release_date = var["block_until"] otherwise timestamp + $GIVEAWAY_PERIOD;
$nice_byte_release_date = timestamp_to_string($byte_release_date, 'date');
// 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
// input
$i = trigger.data;
$account_name = $i.account_name otherwise bounce ("Please specify an account name");
$key = trigger.address||"_"||$account_name;
// load state concerning the CODAA
$cods = var["cods_id"] otherwise false;
$temp_next_accounting_time = var["next_accounting_time"] otherwise timestamp+ $ACCOUNTING_PERIOD;
$temp_interest_next_accounting = var["interest_next_accounting"] otherwise 0;
$temp_pool_balance = var["pool_balance"] otherwise 1e15;
// load state concerning the user
$user_bytes = var[$key||"_bytes"] otherwise 0;
$user_cods = var[$key||"_cods"] otherwise 0;
$user_stake_start = var[$key||"_stake_start"] otherwise timestamp;
$user_predicted_lock_time = var[$key||"_predifcted_lock_time"] otherwise $i.lock_time otherwise $GIVEAWAY_PERIOD;
// 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($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": "{ !$cods}",
"init": "{
}",
"messages": [
{
"app": "asset",
"payload": {
"cap": "{1e15}",
"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"] = $GIVEAWAY_PERIOD;
var["next_accounting_time"] = $next_accounting_time;
var["pool_balance"] = $pool_balance;
}"
}
]
},
{
"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' !");
// Amount received to be blocked to receive free coins
$received_bytes = trigger.output[[asset=base]].amount - 2000;
// free coin computation
$remaining_time = 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 ... interest pot.
$free_cods = $unfair_free_cods * (1 - (0.04 * ln($received_bytes) - 0.31));
$new_interest = $free_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;
var["pool_balance"] = $pool_balance - $free_cods;
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 "||$nice_byte_release_date||". 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 }"
}
]
}
},
{
"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 < 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 }"
}
]
}
},
{
"app": "state",
"state": "{
var[$key||"_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;
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 !$i.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;
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.";
}"
}
]
},
{
"if": "{ !!$i.h or !!trigger.data.help }",
"messages": [
{
"app": "state",
"state": "{
bounce ("use 'block_until' = "||$byte_release_date||" with some bytes (that AA will keep temporary) to claim your free CODs, or send your CODs to 'stake' = <time in days>to stake them start getting interests.");
}"
}
]
},
{
"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_kaccounting"] = 0;
var["pool_balance"] = $pool_balance + $user_cods;
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)||".";
}"
}
]
}
]
}
}
]