Skip to content

Commit

Permalink
Donor Directed Accounts Liquidation (#14)
Browse files Browse the repository at this point in the history
* refactor donation tracking to also keep a struct of the addresses in one place.

* refactor the liquidation of donor directed wallets, in including community wallet case

* patch community wallet veto test

* fix nasty oversight with double counting cumulative deposits.

* community pro_rata calculation and test

* refactor vm_make_payment_no_limit to account for withdraw capabilities being delegated in multisig wallets.

* donor directed wallet liquidation flow tested.

* clean print

* all tests passing.

* Squashed commit of the following:

commit ab1da1d
Author: 0o-de-lally <1364012+0o-de-lally@users.noreply.github.com>
Date:   Fri Apr 14 17:36:50 2023 -0400

    Hard Fork Migrations (#13)

    * add tower state migration

    * migrate community wallet list

    * ancestry struct resources

    * use coin split in genesis migration

    * migrate ancestry and receipts

    * migrates diemaccount cumulative tracker

    * migrate slow wallet

    * patch community wallet migrate

    * epoch migration stub.

    * slow wallet unlock with coin split factor

    * cleanup names
  • Loading branch information
0o-de-lally committed Apr 14, 2023
1 parent ab1da1d commit 8a9c874
Show file tree
Hide file tree
Showing 86 changed files with 2,276 additions and 606 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ compiled_package_info:
? address: "00000000000000000000000000000001"
name: XUS
: DiemFramework
source_digest: EF1AFDD505599DD9943F0CB10F6F3A43DEAF857A5E72E8418911802769CF5545
source_digest: AC18FFADC96F23A35B89DD692B44FA08BACA9F8F5559EC425C6ECDD7C2E09D22
build_flags:
dev_mode: false
test_mode: false
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
- [Function `is_family`](#0x1_Ancestry_is_family)
- [Function `is_family_one_in_list`](#0x1_Ancestry_is_family_one_in_list)
- [Function `any_family_in_list`](#0x1_Ancestry_any_family_in_list)
- [Function `migrate`](#0x1_Ancestry_migrate)
- [Function `fork_migrate`](#0x1_Ancestry_fork_migrate)


<pre><code><b>use</b> <a href="CoreAddresses.md#0x1_CoreAddresses">0x1::CoreAddresses</a>;
Expand Down Expand Up @@ -294,13 +294,13 @@

</details>

<a name="0x1_Ancestry_migrate"></a>
<a name="0x1_Ancestry_fork_migrate"></a>

## Function `migrate`
## Function `fork_migrate`



<pre><code><b>public</b> <b>fun</b> <a href="Ancestry.md#0x1_Ancestry_migrate">migrate</a>(vm: &signer, child_sig: &signer, migrate_tree: vector&lt;<b>address</b>&gt;)
<pre><code><b>public</b> <b>fun</b> <a href="Ancestry.md#0x1_Ancestry_fork_migrate">fork_migrate</a>(vm: &signer, child_sig: &signer, migrate_tree: vector&lt;<b>address</b>&gt;)
</code></pre>


Expand All @@ -309,7 +309,7 @@
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="Ancestry.md#0x1_Ancestry_migrate">migrate</a>(
<pre><code><b>public</b> <b>fun</b> <a href="Ancestry.md#0x1_Ancestry_fork_migrate">fork_migrate</a>(
vm: &signer,
child_sig: &signer,
migrate_tree: vector&lt;<b>address</b>&gt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,6 @@ If you have a mutable BallotTracker instance AND you have the GUID Create Capabi
<b>let</b> b = <a href="Ballot.md#0x1_Ballot">Ballot</a> {

guid: <a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/GUID.md#0x1_GUID_create_with_capability">GUID::create_with_capability</a>(ignored_addr, guid_cap), // Note 0L's modification <b>to</b> Std::GUID, <b>address</b> is ignored.
// issue,
tally_type,
completed: <b>false</b>,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,9 @@ if it is not qualifying it wont be part of the burn funds matching.
<pre><code><b>public</b> <b>fun</b> <a href="CommunityWallet.md#0x1_CommunityWallet_is_comm">is_comm</a>(addr: <b>address</b>): bool {
// The <a href="CommunityWallet.md#0x1_CommunityWallet">CommunityWallet</a> flag is set
<a href="CommunityWallet.md#0x1_CommunityWallet_is_init">is_init</a>(addr) &&
// <b>has</b> <a href="DonorDirected.md#0x1_DonorDirected">DonorDirected</a> instantiated
// <b>has</b> <a href="DonorDirected.md#0x1_DonorDirected">DonorDirected</a> instantiated properly
<a href="DonorDirected.md#0x1_DonorDirected_is_donor_directed">DonorDirected::is_donor_directed</a>(addr) &&
<a href="DonorDirected.md#0x1_DonorDirected_liquidates_to_escrow">DonorDirected::liquidates_to_escrow</a>(addr) &&
// <b>has</b> <a href="MultiSig.md#0x1_MultiSig">MultiSig</a> instantialized
<a href="MultiSig.md#0x1_MultiSig_is_init">MultiSig::is_init</a>(addr) &&
// multisig <b>has</b> minimum requirement of 3 signatures, and minimum list of 5 signers, and a minimum of 3/5 threshold. I.e. OK <b>to</b> have 4/5 signatures.
Expand Down Expand Up @@ -337,7 +338,9 @@ These transactions can be sent directly to DonorDirected, but this is a helper t

<b>assert</b>!(!fam, <a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/Errors.md#0x1_Errors_invalid_argument">Errors::invalid_argument</a>(<a href="CommunityWallet.md#0x1_CommunityWallet_ESIGNERS_SYBIL">ESIGNERS_SYBIL</a>));

<a href="DonorDirected.md#0x1_DonorDirected_set_donor_directed">DonorDirected::set_donor_directed</a>(&sig);
// set <b>as</b> donor directed <b>with</b> any liquidation going <b>to</b> infrastructure escrow
<b>let</b> liquidate_to_infra_escrow = <b>true</b>;
<a href="DonorDirected.md#0x1_DonorDirected_set_donor_directed">DonorDirected::set_donor_directed</a>(&sig, liquidate_to_infra_escrow);
<a href="DonorDirected.md#0x1_DonorDirected_make_multisig">DonorDirected::make_multisig</a>(&sig, 3, init_signers);
}
</code></pre>
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ The voting mechanism is a TurnoutTally. Such votes ajust the threshold for passi
- [Function `is_authorized`](#0x1_DonorDirectedGovernance_is_authorized)
- [Function `get_user_donations`](#0x1_DonorDirectedGovernance_get_user_donations)
- [Function `vote_veto`](#0x1_DonorDirectedGovernance_vote_veto)
- [Function `vote_liquidation`](#0x1_DonorDirectedGovernance_vote_liquidation)
- [Function `veto_by_id`](#0x1_DonorDirectedGovernance_veto_by_id)
- [Function `sync_ballot_and_tx_expiration`](#0x1_DonorDirectedGovernance_sync_ballot_and_tx_expiration)
- [Function `propose_veto`](#0x1_DonorDirectedGovernance_propose_veto)
- [Function `propose_liquidate`](#0x1_DonorDirectedGovernance_propose_liquidate)
- [Function `propose_gov`](#0x1_DonorDirectedGovernance_propose_gov)
- [Function `is_unique_proposal`](#0x1_DonorDirectedGovernance_is_unique_proposal)


<pre><code><b>use</b> <a href="Ballot.md#0x1_Ballot">0x1::Ballot</a>;
Expand All @@ -39,6 +41,7 @@ The voting mechanism is a TurnoutTally. Such votes ajust the threshold for passi
<b>use</b> <a href="Receipts.md#0x1_Receipts">0x1::Receipts</a>;
<b>use</b> <a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/Signer.md#0x1_Signer">0x1::Signer</a>;
<b>use</b> <a href="TurnoutTally.md#0x1_TurnoutTally">0x1::TurnoutTally</a>;
<b>use</b> <a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/Vector.md#0x1_Vector">0x1::Vector</a>;
</code></pre>


Expand Down Expand Up @@ -342,6 +345,48 @@ private function to vote on a ballot based on a Donor's voting power.



</details>

<a name="0x1_DonorDirectedGovernance_vote_liquidation"></a>

## Function `vote_liquidation`

Liquidation tally only. The handler for liquidation exists in DonorDirected, where a tx script will call it.


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_vote_liquidation">vote_liquidation</a>(donor: &signer, multisig_address: <b>address</b>): <a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/Option.md#0x1_Option_Option">Option::Option</a>&lt;bool&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_vote_liquidation">vote_liquidation</a>(donor: &signer, multisig_address: <b>address</b>): <a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/Option.md#0x1_Option">Option</a>&lt;bool&gt; <b>acquires</b> <a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_Governance">Governance</a>{
<a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_assert_authorized">assert_authorized</a>(donor, multisig_address);
<b>let</b> state = <b>borrow_global_mut</b>&lt;<a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_Governance">Governance</a>&lt;<a href="TurnoutTally.md#0x1_TurnoutTally">TurnoutTally</a>&lt;<a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_Liquidate">Liquidate</a>&gt;&gt;&gt;(multisig_address);

// for liquidation there is only ever one proposal, which never expires
// so always taket the first one from pending.
<b>let</b> pending_list = <a href="Ballot.md#0x1_Ballot_get_list_ballots_by_enum_mut">Ballot::get_list_ballots_by_enum_mut</a>(&<b>mut</b> state.tracker, <a href="Ballot.md#0x1_Ballot_get_pending_enum">Ballot::get_pending_enum</a>());
// print(pending_list);

<b>if</b> (<a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/Vector.md#0x1_Vector_is_empty">Vector::is_empty</a>(pending_list)) {
<b>return</b> <a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/Option.md#0x1_Option_none">Option::none</a>&lt;bool&gt;()
};

<b>let</b> ballot = <a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/Vector.md#0x1_Vector_borrow_mut">Vector::borrow_mut</a>(pending_list, 0);
<b>let</b> ballot_guid = <a href="Ballot.md#0x1_Ballot_get_ballot_id">Ballot::get_ballot_id</a>(ballot);
<b>let</b> tally_state = <a href="Ballot.md#0x1_Ballot_get_type_struct_mut">Ballot::get_type_struct_mut</a>(ballot);
<b>let</b> user_weight = <a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_get_user_donations">get_user_donations</a>(multisig_address, <a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/Signer.md#0x1_Signer_address_of">Signer::address_of</a>(donor));

<a href="TurnoutTally.md#0x1_TurnoutTally_vote">TurnoutTally::vote</a>(donor, tally_state, &ballot_guid, <b>true</b>, user_weight)
}
</code></pre>



</details>

<a name="0x1_DonorDirectedGovernance_veto_by_id"></a>
Expand Down Expand Up @@ -415,6 +460,8 @@ should only be called by the DonorDirected.move so that the handlers can be call

## Function `propose_veto`

only DonorDirected can call this. The veto and liquidate handlers need
to be located there. So users should not call functions here.


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_propose_veto">propose_veto</a>(cap: &<a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/GUID.md#0x1_GUID_CreateCapability">GUID::CreateCapability</a>, guid: &<a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/GUID.md#0x1_GUID_ID">GUID::ID</a>, epochs_duration: u64)
Expand All @@ -426,7 +473,7 @@ should only be called by the DonorDirected.move so that the handlers can be call
<summary>Implementation</summary>


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_propose_veto">propose_veto</a>(
<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_propose_veto">propose_veto</a>(
cap: &<a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/GUID.md#0x1_GUID_CreateCapability">GUID::CreateCapability</a>,
guid: &<a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/GUID.md#0x1_GUID_ID">GUID::ID</a>, // Id of initiated transaction.
epochs_duration: u64
Expand Down Expand Up @@ -455,7 +502,7 @@ should only be called by the DonorDirected.move so that the handlers can be call
<summary>Implementation</summary>


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_propose_liquidate">propose_liquidate</a>(
<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_propose_liquidate">propose_liquidate</a>(
cap: &<a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/GUID.md#0x1_GUID_CreateCapability">GUID::CreateCapability</a>,
epochs_duration: u64
) <b>acquires</b> <a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_Governance">Governance</a> {
Expand Down Expand Up @@ -488,7 +535,8 @@ a private function to propose a ballot for a veto. This is called by a verified
<b>let</b> directed_account = <a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/GUID.md#0x1_GUID_get_capability_address">GUID::get_capability_address</a>(cap);
<b>let</b> gov_state = <b>borrow_global_mut</b>&lt;<a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_Governance">Governance</a>&lt;<a href="TurnoutTally.md#0x1_TurnoutTally">TurnoutTally</a>&lt;GovAction&gt;&gt;&gt;(directed_account);

// <b>let</b> data = <a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_Veto">Veto</a> { guid: proposal_guid };
<b>if</b> (!<a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_is_unique_proposal">is_unique_proposal</a>(&gov_state.tracker, &data)) <b>return</b>;

// what's the maximum universe of valid votes.
<b>let</b> max_votes_enrollment = <a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_get_enrollment">get_enrollment</a>(directed_account);
<b>if</b> (epochs_duration &lt; 7) {
Expand All @@ -499,7 +547,6 @@ a private function to propose a ballot for a veto. This is called by a verified
<b>let</b> max_extensions = 0; // infinite

<b>let</b> t = <a href="TurnoutTally.md#0x1_TurnoutTally_new_tally_struct">TurnoutTally::new_tally_struct</a>(
// cap,
data,
max_votes_enrollment,
deadline,
Expand All @@ -512,4 +559,43 @@ a private function to propose a ballot for a veto. This is called by a verified



</details>

<a name="0x1_DonorDirectedGovernance_is_unique_proposal"></a>

## Function `is_unique_proposal`

Check if a proposal has already been made for this transaction.


<pre><code><b>fun</b> <a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_is_unique_proposal">is_unique_proposal</a>&lt;GovAction: drop, store&gt;(tracker: &<a href="Ballot.md#0x1_Ballot_BallotTracker">Ballot::BallotTracker</a>&lt;<a href="TurnoutTally.md#0x1_TurnoutTally_TurnoutTally">TurnoutTally::TurnoutTally</a>&lt;GovAction&gt;&gt;, data: &GovAction): bool
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>fun</b> <a href="DonorDirectedGovernance.md#0x1_DonorDirectedGovernance_is_unique_proposal">is_unique_proposal</a>&lt;GovAction: drop + store&gt;(tracker: &BallotTracker&lt;<a href="TurnoutTally.md#0x1_TurnoutTally">TurnoutTally</a>&lt;GovAction&gt;&gt;, data: &GovAction): bool {
// NOTE: <a href="Ballot.md#0x1_Ballot">Ballot</a>.<b>move</b> does not check for duplicates. We need <b>to</b> check here.
<b>let</b> list_pending = <a href="Ballot.md#0x1_Ballot_get_list_ballots_by_enum">Ballot::get_list_ballots_by_enum</a>(tracker, <a href="Ballot.md#0x1_Ballot_get_pending_enum">Ballot::get_pending_enum</a>());

<b>let</b> len = <a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/Vector.md#0x1_Vector_length">Vector::length</a>(list_pending);
<b>let</b> i = 0;

<b>while</b> (i &lt; len) {
<b>let</b> ballot = <a href="../../../../../../../DPN/releases/artifacts/current/build/MoveStdlib/docs/Vector.md#0x1_Vector_borrow">Vector::borrow</a>(list_pending, i);
<b>let</b> ballot_data = <a href="Ballot.md#0x1_Ballot_get_type_struct">Ballot::get_type_struct</a>(ballot);

<b>if</b> (<a href="TurnoutTally.md#0x1_TurnoutTally_get_tally_data">TurnoutTally::get_tally_data</a>(ballot_data) == data) <b>return</b> <b>false</b>;

i = i + 1;
};
<b>true</b>
}
</code></pre>



</details>
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ Called in genesis to initialize timer

## Function `epoch_finished`

Migrate the timer in a fork.
Check to see if epoch is finished
Simply checks if the elapsed time is greater than the epoch time

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@



- [Function `migrate_user`](#0x1_GenesisMigration_migrate_user)
- [Function `fork_migrate_account`](#0x1_GenesisMigration_fork_migrate_account)
- [Function `are_you_a_val_or_oper`](#0x1_GenesisMigration_are_you_a_val_or_oper)


Expand All @@ -21,14 +21,14 @@



<a name="0x1_GenesisMigration_migrate_user"></a>
<a name="0x1_GenesisMigration_fork_migrate_account"></a>

## Function `migrate_user`
## Function `fork_migrate_account`

Called by root in genesis to initialize the GAS coin


<pre><code><b>public</b> <b>fun</b> <a href="GenesisMigration.md#0x1_GenesisMigration_migrate_user">migrate_user</a>(vm: &signer, user_sig: &signer, auth_key: vector&lt;u8&gt;, balance: u64)
<pre><code><b>public</b> <b>fun</b> <a href="GenesisMigration.md#0x1_GenesisMigration_fork_migrate_account">fork_migrate_account</a>(vm: &signer, user_sig: &signer, auth_key: vector&lt;u8&gt;, balance: u64)
</code></pre>


Expand All @@ -37,7 +37,7 @@ Called by root in genesis to initialize the GAS coin
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="GenesisMigration.md#0x1_GenesisMigration_migrate_user">migrate_user</a>(
<pre><code><b>public</b> <b>fun</b> <a href="GenesisMigration.md#0x1_GenesisMigration_fork_migrate_account">fork_migrate_account</a>(
vm: &signer,
user_sig: &signer,
// user_addr: <b>address</b>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ Get the constants for the current network
epoch_mining_thres_lower: 1, // in testnet, staging, we don't want
// <b>to</b> wait too long between proofs.
epoch_mining_thres_upper: 72, // upper bound enforced at 20 mins per proof.
epoch_slow_wallet_unlock: 10000000,
epoch_slow_wallet_unlock: 1000 * <a href="Globals.md#0x1_Globals_get_coin_split_factor">get_coin_split_factor</a>() * <a href="Globals.md#0x1_Globals_COIN_SCALING_FACTOR">COIN_SCALING_FACTOR</a>,
min_blocks_per_epoch: 1000,
vouch_threshold: 0,
signing_threshold_pct: 3,
Expand All @@ -543,7 +543,7 @@ Get the constants for the current network
vdf_security_baseline: 512,
epoch_mining_thres_lower: 7, // NOTE: bootstrapping, allowance for operator error.
epoch_mining_thres_upper: 72, // upper bound enforced at 20 mins per proof.
epoch_slow_wallet_unlock: 1000 * <a href="Globals.md#0x1_Globals_COIN_SCALING_FACTOR">COIN_SCALING_FACTOR</a>, // approx 10 years for largest accounts in genesis.
epoch_slow_wallet_unlock: 1000 * <a href="Globals.md#0x1_Globals_get_coin_split_factor">get_coin_split_factor</a>() * <a href="Globals.md#0x1_Globals_COIN_SCALING_FACTOR">COIN_SCALING_FACTOR</a>, // approx 10 years for largest accounts in genesis.
min_blocks_per_epoch: 10000,
vouch_threshold: 2, // Production is 2 vouchers per validator
signing_threshold_pct: 3,
Expand Down
Loading

0 comments on commit 8a9c874

Please sign in to comment.