-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: initial commit and test structure
- Loading branch information
0 parents
commit 10c2536
Showing
14 changed files
with
3,336 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
name: Compile and Test Contracts | ||
|
||
on: [push] | ||
|
||
jobs: | ||
build-and-test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Use Node.js 22.x | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: 22.x | ||
- run: npm install -g @aeternity/aeproject | ||
- run: npm ci | ||
- run: aeproject env | ||
- run: aeproject test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
node_modules | ||
.idea | ||
generated/**.aes.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
include "./HCElection.aes" | ||
include "./StakingValidator.aes" | ||
include "./MainStaking.aes" | ||
|
||
payable contract DelegatedStaking = | ||
|
||
record state = | ||
{ staking_validator : option(StakingValidator) | ||
, main_staking : MainStaking | ||
, stakes : map(address, int) } | ||
|
||
stateful entrypoint init(main_staking : MainStaking) = | ||
{ staking_validator = None, | ||
main_staking = main_staking, | ||
stakes = {} } | ||
|
||
payable stateful entrypoint register_validator() = | ||
put(state{ staking_validator = Some(state.main_staking.new_validator(value = Call.value)) }) | ||
|
||
function get_staking_validator() = | ||
switch(state.staking_validator) | ||
Some(staking_validator) => staking_validator | ||
None => abort("register_validator not yet called") | ||
|
||
payable stateful entrypoint stake() = | ||
state.main_staking.stake(value = Call.value, Contract.address) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
include "List.aes" | ||
include "Pair.aes" | ||
include "./MainStaking.aes" | ||
|
||
contract HCElection = | ||
record epoch_info = | ||
{ start : int, | ||
length : int, | ||
seed : option(bytes()), | ||
staking_distribution : option(list(address * int)) | ||
} | ||
|
||
record pin_reward_info = | ||
{ base : int, | ||
current : int, | ||
carry_over : int | ||
} | ||
|
||
record state = | ||
{ main_staking_ct : MainStaking, | ||
leader : address, | ||
added_stake : int, | ||
epoch : int, | ||
epochs : map(int, epoch_info), | ||
pin : option(bytes()), | ||
pin_reward : pin_reward_info | ||
} | ||
|
||
entrypoint init(main_staking_ct : MainStaking) = | ||
{ main_staking_ct = main_staking_ct, | ||
leader = Contract.address, | ||
added_stake = 0, | ||
epoch = 0, | ||
epochs = {}, | ||
pin = None, | ||
pin_reward = {base = 0, current = 0, carry_over = 0} } | ||
|
||
stateful entrypoint init_epochs(epoch_length : int, base_pin_reward : int) = | ||
assert_protocol_call() | ||
//require(Chain.block_height == 0, "Only in genesis") | ||
put(state{ epochs = { [0] = mk_epoch_info(0, 1, None, None), | ||
[1] = mk_epoch_info(1, epoch_length, None, Some(state.main_staking_ct.sorted_validators())), | ||
[2] = mk_epoch_info(epoch_length + 1, epoch_length, None, Some(state.main_staking_ct.sorted_validators())), | ||
[3] = mk_epoch_info(2 * epoch_length + 1, epoch_length, None, Some(state.main_staking_ct.sorted_validators())), | ||
[4] = mk_epoch_info(3 * epoch_length + 1, epoch_length, None, Some(state.main_staking_ct.sorted_validators())) | ||
}, | ||
epoch = 1, | ||
pin_reward.base = base_pin_reward | ||
}) | ||
|
||
function mk_epoch_info(start : int, | ||
length : int, | ||
seed : option(bytes), | ||
staking_distribution : option(list(address * int))) = | ||
{start = start, length = length, seed = seed, staking_distribution = staking_distribution} | ||
|
||
stateful entrypoint step(leader : address) = | ||
assert_protocol_call() | ||
put(state{ leader = leader }) | ||
|
||
stateful entrypoint step_micro(leader : address) = | ||
assert_protocol_call() | ||
put(state{ leader = leader }) | ||
|
||
stateful entrypoint step_eoe(leader : address, seed : bytes(), epoch_adjust : int, | ||
next_base_pin_reward : int, carry_over_flag : bool) = | ||
assert_protocol_call() | ||
let epoch = state.epoch | ||
let ei = state.epochs[epoch] | ||
// pin rewards | ||
let next_carry_over = calc_carry_over(carry_over_flag) | ||
let next_base = calc_next_base_reward(next_base_pin_reward) | ||
let next_reward = next_base + next_carry_over | ||
let pr = {current = next_reward, carry_over = next_carry_over, base = next_base} | ||
// update epochs | ||
require(ei.start + ei.length - 1 == Chain.block_height, "This is not the end") | ||
let ei2 = state.epochs[epoch + 2] | ||
let ei_adjust = state.epochs[epoch + 3]{ length = ei2.length + epoch_adjust } | ||
let new_epochs = { [epoch] = state.epochs[epoch], | ||
[epoch + 1] = state.epochs[epoch + 1], | ||
[epoch + 2] = state.epochs[epoch + 2]{ seed = Some(seed) }, | ||
[epoch + 3] = ei_adjust, | ||
[epoch + 4] = mk_epoch_info(ei_adjust.start + ei_adjust.length, ei_adjust.length, None, | ||
Some(state.main_staking_ct.sorted_validators())) | ||
} | ||
|
||
put(state{ leader = leader, | ||
epoch = epoch + 1, | ||
epochs = new_epochs, | ||
pin = None, | ||
pin_reward = pr}) | ||
|
||
stateful entrypoint pin(proof : bytes()) = | ||
let epoch = state.epoch | ||
let last = state.epochs[epoch].start + state.epochs[epoch].length - 1 | ||
require(Chain.block_height == last, "Only in last block") | ||
require(Call.caller == state.leader, "Must be called by the last leader of epoch") | ||
put(state{pin = Some(proof)}) | ||
|
||
entrypoint leader() = | ||
state.leader | ||
|
||
// entrypoint added_stake() = | ||
// state.added_stake | ||
|
||
entrypoint epoch() = | ||
state.epoch | ||
|
||
entrypoint epoch_length() = | ||
state.epochs[state.epoch].length | ||
|
||
entrypoint epoch_info() = | ||
(state.epoch, state.epochs[state.epoch]) | ||
|
||
entrypoint epoch_info_epoch(epoch : int) = | ||
require(epoch >= state.epoch - 1 && epoch =< state.epoch + 2, "Epoch not in scope") | ||
state.epochs[epoch] | ||
|
||
entrypoint staking_contract() = | ||
state.main_staking_ct | ||
|
||
entrypoint validator_schedule(seed : bytes(), validators : list(address * int), length : int) = | ||
let total_stake = List.foldl((+), 0, List.map(Pair.snd, validators)) | ||
// One extra hash operation to convert from bytes() to bytes(32)/hash | ||
validator_schedule_(Crypto.blake2b(seed), (s) => Bytes.to_int(s) mod total_stake, validators, length, []) | ||
|
||
entrypoint pin_info() = | ||
state.pin | ||
|
||
entrypoint pin_reward_info() = | ||
state.pin_reward | ||
|
||
function | ||
validator_schedule_(_, _, _, 0, schedule) = List.reverse(schedule) | ||
validator_schedule_(seed0, rnd, validators, n, schedule) = | ||
let seed = Crypto.blake2b(seed0) | ||
let validator = pick_validator(rnd(seed), validators) | ||
validator_schedule_(seed, rnd, validators, n - 1, validator :: schedule) | ||
|
||
function | ||
pick_validator(n, (validator, stake) :: _) | n < stake = validator | ||
pick_validator(n, (_, stake) :: validators) = pick_validator(n - stake, validators) | ||
|
||
function assert_protocol_call() = | ||
require(Call.caller == Contract.creator, "Must be called by the protocol") | ||
|
||
function calc_carry_over(carry_over_flag : bool) = | ||
let ei = state.pin_reward | ||
if (carry_over_flag) | ||
ei.base + ei.carry_over | ||
else | ||
0 | ||
|
||
function calc_next_base_reward(next_base_pin_reward : int) = | ||
if ( next_base_pin_reward >= 0 ) | ||
next_base_pin_reward | ||
else | ||
state.pin_reward.base | ||
|
||
// function accum_stake((accum, total_s, current_hash, network_id), (addr, stake)) = | ||
// ((addr, stake) :: accum, stake + total_s, current_hash, network_id) |
Oops, something went wrong.