Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[upgrade] donor voice migration #88

Merged
merged 55 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
059df06
Vouch validators fixes
hemulin Oct 30, 2023
4c66376
update makefile
0o-de-lally Oct 30, 2023
ef35292
patch makefile use CHAIN = testnet
0o-de-lally Oct 30, 2023
038e42e
[query] create query view for validator config (#73)
sirouk Oct 31, 2023
9a9b65a
[tools] fix network address registration for validators (#74)
sirouk Nov 1, 2023
e124807
`update -p diem` updates cargo.lock (#75)
sirouk Nov 1, 2023
95435c1
[tools] remove tbd query subcommands (#76)
0o-de-lally Nov 2, 2023
bac68f8
Patch config init (#77)
sirouk Nov 2, 2023
1b3a19e
[tower] fix lazy counter reset (#78)
sirouk Nov 2, 2023
7532e24
[tower] patch tower counter add tests (#81)
sirouk Nov 3, 2023
9e14488
[upgrades] git commit hash included on-chain on upgrades (#80)
sirouk Nov 3, 2023
b8df3a2
[tools] config tool fullnode-init subcommand (#79)
sirouk Nov 3, 2023
8a824fb
[Move] patch burn tracker (#82)
sirouk Nov 4, 2023
7a18375
[upgrade] get actual git head for framework on upgrades
0o-de-lally Nov 4, 2023
99cade9
[tools] build the framework before genesis (#84)
sirouk Nov 5, 2023
be4f8d2
[move] fix lifetime burn info (#85)
hemulin Nov 5, 2023
eab6f76
[move] patch thermostat on epoch boundary, add instrumentation (#87)
sirouk Nov 5, 2023
1363fe7
[move] default POF bid from genesis (#86)
hemulin Nov 5, 2023
66449e4
migrate user receipts
0o-de-lally Nov 5, 2023
3cbfcd3
update fixture
0o-de-lally Nov 5, 2023
0218fdc
receipts migration passing
0o-de-lally Nov 5, 2023
cc33414
patch pre-commit
0o-de-lally Nov 7, 2023
561360e
scaffold genesis functions to rebuild community wallet structs in new…
0o-de-lally Nov 6, 2023
214d3da
add get_cw_cumu_deposits
0o-de-lally Nov 6, 2023
eb31f8c
tests
0o-de-lally Nov 6, 2023
e2cd139
check cumu
0o-de-lally Nov 6, 2023
b54cd92
include audit test
0o-de-lally Nov 6, 2023
7174188
updating cw from deposit receipts
0o-de-lally Nov 7, 2023
6eb4ce5
text
0o-de-lally Nov 7, 2023
df7c8b0
inclue split factor in receipts and cw migration
0o-de-lally Nov 7, 2023
6dd1298
add split to tests
0o-de-lally Nov 7, 2023
eb5c9aa
cleanup
0o-de-lally Nov 7, 2023
4cbcf27
consolidate name to donor-voice
0o-de-lally Nov 5, 2023
0aaa896
create rust genesis_migrate_donor_voice
0o-de-lally Nov 5, 2023
eb6c8cc
framework build
0o-de-lally Nov 5, 2023
188be64
init from community wallet
0o-de-lally Nov 5, 2023
ef10a5a
add to genesis recovery
0o-de-lally Nov 5, 2023
858ec32
simple migration of communtiy wallets. Users and authorities will nee…
0o-de-lally Nov 5, 2023
9c7a949
fmt
0o-de-lally Nov 7, 2023
55d2aa4
rename
0o-de-lally Nov 7, 2023
e33587d
rebase from migrate-match-index
0o-de-lally Nov 7, 2023
cb42440
fmt
0o-de-lally Nov 7, 2023
adab47d
update genesis makefile
0o-de-lally Nov 7, 2023
9fa45c1
create cumulative_deposits genesis function
0o-de-lally Nov 7, 2023
7cf645b
call cumu deposit from vm genesis
0o-de-lally Nov 7, 2023
88ce1e9
remove total calc which was causing overflow. patch tests
0o-de-lally Nov 7, 2023
429ca4e
patch
0o-de-lally Nov 7, 2023
a10ccf2
patch move build, tests passing
0o-de-lally Nov 7, 2023
524fff1
text
0o-de-lally Nov 7, 2023
152fc36
fmt
0o-de-lally Nov 7, 2023
e35fa1a
switch from Hashmap to BTree since the order goes to genesis, and has…
0o-de-lally Nov 7, 2023
0273696
patch missing fixture
0o-de-lally Nov 7, 2023
69a1793
fix issue with test deleting fixture
0o-de-lally Nov 7, 2023
b2e069c
Squashed commit of the following:
0o-de-lally Nov 7, 2023
a40161c
Merge branch 'main' into donor-voice-migration
0o-de-lally Nov 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 55 additions & 60 deletions framework/cached-packages/src/libra_framework_sdk_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,33 +219,33 @@ pub enum EntryFunctionCall {
should_pass: bool,
},

DonorDirectedMakeDonorDirectedTx {
DonorVoiceMakeDonorVoiceTx {
init_signers: Vec<AccountAddress>,
cfg_n_signers: u64,
},

DonorDirectedProposeLiquidateTx {
DonorVoiceProposeLiquidateTx {
multisig_address: AccountAddress,
},

DonorDirectedProposePaymentTx {
DonorVoiceProposePaymentTx {
multisig_address: AccountAddress,
payee: AccountAddress,
value: u64,
description: Vec<u8>,
},

DonorDirectedProposeVetoTx {
DonorVoiceProposeVetoTx {
multisig_address: AccountAddress,
id: u64,
},

DonorDirectedVoteLiquidationTx {
DonorVoiceVoteLiquidationTx {
multisig_address: AccountAddress,
},

/// Entry functiont to vote the veto.
DonorDirectedVoteVetoTx {
DonorVoiceVoteVetoTx {
multisig_address: AccountAddress,
id: u64,
},
Expand Down Expand Up @@ -680,30 +680,30 @@ impl EntryFunctionCall {
proposal_id,
should_pass,
} => diem_governance_vote(proposal_id, should_pass),
DonorDirectedMakeDonorDirectedTx {
DonorVoiceMakeDonorVoiceTx {
init_signers,
cfg_n_signers,
} => donor_directed_make_donor_directed_tx(init_signers, cfg_n_signers),
DonorDirectedProposeLiquidateTx { multisig_address } => {
donor_directed_propose_liquidate_tx(multisig_address)
} => donor_voice_make_donor_voice_tx(init_signers, cfg_n_signers),
DonorVoiceProposeLiquidateTx { multisig_address } => {
donor_voice_propose_liquidate_tx(multisig_address)
}
DonorDirectedProposePaymentTx {
DonorVoiceProposePaymentTx {
multisig_address,
payee,
value,
description,
} => donor_directed_propose_payment_tx(multisig_address, payee, value, description),
DonorDirectedProposeVetoTx {
} => donor_voice_propose_payment_tx(multisig_address, payee, value, description),
DonorVoiceProposeVetoTx {
multisig_address,
id,
} => donor_directed_propose_veto_tx(multisig_address, id),
DonorDirectedVoteLiquidationTx { multisig_address } => {
donor_directed_vote_liquidation_tx(multisig_address)
} => donor_voice_propose_veto_tx(multisig_address, id),
DonorVoiceVoteLiquidationTx { multisig_address } => {
donor_voice_vote_liquidation_tx(multisig_address)
}
DonorDirectedVoteVetoTx {
DonorVoiceVoteVetoTx {
multisig_address,
id,
} => donor_directed_vote_veto_tx(multisig_address, id),
} => donor_voice_vote_veto_tx(multisig_address, id),
JailUnjailByVoucher { addr } => jail_unjail_by_voucher(addr),
GasCoinClaimMintCapability {} => gas_coin_claim_mint_capability(),
GasCoinDelegateMintCapability { to } => gas_coin_delegate_mint_capability(to),
Expand Down Expand Up @@ -1380,7 +1380,7 @@ pub fn diem_governance_vote(proposal_id: u64, should_pass: bool) -> TransactionP
))
}

pub fn donor_directed_make_donor_directed_tx(
pub fn donor_voice_make_donor_voice_tx(
init_signers: Vec<AccountAddress>,
cfg_n_signers: u64,
) -> TransactionPayload {
Expand All @@ -1390,9 +1390,9 @@ pub fn donor_directed_make_donor_directed_tx(
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1,
]),
ident_str!("donor_directed").to_owned(),
ident_str!("donor_voice").to_owned(),
),
ident_str!("make_donor_directed_tx").to_owned(),
ident_str!("make_donor_voice_tx").to_owned(),
vec![],
vec![
bcs::to_bytes(&init_signers).unwrap(),
Expand All @@ -1401,22 +1401,22 @@ pub fn donor_directed_make_donor_directed_tx(
))
}

pub fn donor_directed_propose_liquidate_tx(multisig_address: AccountAddress) -> TransactionPayload {
pub fn donor_voice_propose_liquidate_tx(multisig_address: AccountAddress) -> TransactionPayload {
TransactionPayload::EntryFunction(EntryFunction::new(
ModuleId::new(
AccountAddress::new([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1,
]),
ident_str!("donor_directed").to_owned(),
ident_str!("donor_voice").to_owned(),
),
ident_str!("propose_liquidate_tx").to_owned(),
vec![],
vec![bcs::to_bytes(&multisig_address).unwrap()],
))
}

pub fn donor_directed_propose_payment_tx(
pub fn donor_voice_propose_payment_tx(
multisig_address: AccountAddress,
payee: AccountAddress,
value: u64,
Expand All @@ -1428,7 +1428,7 @@ pub fn donor_directed_propose_payment_tx(
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1,
]),
ident_str!("donor_directed").to_owned(),
ident_str!("donor_voice").to_owned(),
),
ident_str!("propose_payment_tx").to_owned(),
vec![],
Expand All @@ -1441,7 +1441,7 @@ pub fn donor_directed_propose_payment_tx(
))
}

pub fn donor_directed_propose_veto_tx(
pub fn donor_voice_propose_veto_tx(
multisig_address: AccountAddress,
id: u64,
) -> TransactionPayload {
Expand All @@ -1451,7 +1451,7 @@ pub fn donor_directed_propose_veto_tx(
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1,
]),
ident_str!("donor_directed").to_owned(),
ident_str!("donor_voice").to_owned(),
),
ident_str!("propose_veto_tx").to_owned(),
vec![],
Expand All @@ -1462,14 +1462,14 @@ pub fn donor_directed_propose_veto_tx(
))
}

pub fn donor_directed_vote_liquidation_tx(multisig_address: AccountAddress) -> TransactionPayload {
pub fn donor_voice_vote_liquidation_tx(multisig_address: AccountAddress) -> TransactionPayload {
TransactionPayload::EntryFunction(EntryFunction::new(
ModuleId::new(
AccountAddress::new([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1,
]),
ident_str!("donor_directed").to_owned(),
ident_str!("donor_voice").to_owned(),
),
ident_str!("vote_liquidation_tx").to_owned(),
vec![],
Expand All @@ -1478,17 +1478,14 @@ pub fn donor_directed_vote_liquidation_tx(multisig_address: AccountAddress) -> T
}

/// Entry functiont to vote the veto.
pub fn donor_directed_vote_veto_tx(
multisig_address: AccountAddress,
id: u64,
) -> TransactionPayload {
pub fn donor_voice_vote_veto_tx(multisig_address: AccountAddress, id: u64) -> TransactionPayload {
TransactionPayload::EntryFunction(EntryFunction::new(
ModuleId::new(
AccountAddress::new([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1,
]),
ident_str!("donor_directed").to_owned(),
ident_str!("donor_voice").to_owned(),
),
ident_str!("vote_veto_tx").to_owned(),
vec![],
Expand Down Expand Up @@ -2642,11 +2639,11 @@ mod decoder {
}
}

pub fn donor_directed_make_donor_directed_tx(
pub fn donor_voice_make_donor_voice_tx(
payload: &TransactionPayload,
) -> Option<EntryFunctionCall> {
if let TransactionPayload::EntryFunction(script) = payload {
Some(EntryFunctionCall::DonorDirectedMakeDonorDirectedTx {
Some(EntryFunctionCall::DonorVoiceMakeDonorVoiceTx {
init_signers: bcs::from_bytes(script.args().get(0)?).ok()?,
cfg_n_signers: bcs::from_bytes(script.args().get(1)?).ok()?,
})
Expand All @@ -2655,23 +2652,23 @@ mod decoder {
}
}

pub fn donor_directed_propose_liquidate_tx(
pub fn donor_voice_propose_liquidate_tx(
payload: &TransactionPayload,
) -> Option<EntryFunctionCall> {
if let TransactionPayload::EntryFunction(script) = payload {
Some(EntryFunctionCall::DonorDirectedProposeLiquidateTx {
Some(EntryFunctionCall::DonorVoiceProposeLiquidateTx {
multisig_address: bcs::from_bytes(script.args().get(0)?).ok()?,
})
} else {
None
}
}

pub fn donor_directed_propose_payment_tx(
pub fn donor_voice_propose_payment_tx(
payload: &TransactionPayload,
) -> Option<EntryFunctionCall> {
if let TransactionPayload::EntryFunction(script) = payload {
Some(EntryFunctionCall::DonorDirectedProposePaymentTx {
Some(EntryFunctionCall::DonorVoiceProposePaymentTx {
multisig_address: bcs::from_bytes(script.args().get(0)?).ok()?,
payee: bcs::from_bytes(script.args().get(1)?).ok()?,
value: bcs::from_bytes(script.args().get(2)?).ok()?,
Expand All @@ -2682,11 +2679,9 @@ mod decoder {
}
}

pub fn donor_directed_propose_veto_tx(
payload: &TransactionPayload,
) -> Option<EntryFunctionCall> {
pub fn donor_voice_propose_veto_tx(payload: &TransactionPayload) -> Option<EntryFunctionCall> {
if let TransactionPayload::EntryFunction(script) = payload {
Some(EntryFunctionCall::DonorDirectedProposeVetoTx {
Some(EntryFunctionCall::DonorVoiceProposeVetoTx {
multisig_address: bcs::from_bytes(script.args().get(0)?).ok()?,
id: bcs::from_bytes(script.args().get(1)?).ok()?,
})
Expand All @@ -2695,21 +2690,21 @@ mod decoder {
}
}

pub fn donor_directed_vote_liquidation_tx(
pub fn donor_voice_vote_liquidation_tx(
payload: &TransactionPayload,
) -> Option<EntryFunctionCall> {
if let TransactionPayload::EntryFunction(script) = payload {
Some(EntryFunctionCall::DonorDirectedVoteLiquidationTx {
Some(EntryFunctionCall::DonorVoiceVoteLiquidationTx {
multisig_address: bcs::from_bytes(script.args().get(0)?).ok()?,
})
} else {
None
}
}

pub fn donor_directed_vote_veto_tx(payload: &TransactionPayload) -> Option<EntryFunctionCall> {
pub fn donor_voice_vote_veto_tx(payload: &TransactionPayload) -> Option<EntryFunctionCall> {
if let TransactionPayload::EntryFunction(script) = payload {
Some(EntryFunctionCall::DonorDirectedVoteVetoTx {
Some(EntryFunctionCall::DonorVoiceVoteVetoTx {
multisig_address: bcs::from_bytes(script.args().get(0)?).ok()?,
id: bcs::from_bytes(script.args().get(1)?).ok()?,
})
Expand Down Expand Up @@ -3312,28 +3307,28 @@ static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazy<EntryFunctionDecoderMa
Box::new(decoder::diem_governance_vote),
);
map.insert(
"donor_directed_make_donor_directed_tx".to_string(),
Box::new(decoder::donor_directed_make_donor_directed_tx),
"donor_voice_make_donor_voice_tx".to_string(),
Box::new(decoder::donor_voice_make_donor_voice_tx),
);
map.insert(
"donor_directed_propose_liquidate_tx".to_string(),
Box::new(decoder::donor_directed_propose_liquidate_tx),
"donor_voice_propose_liquidate_tx".to_string(),
Box::new(decoder::donor_voice_propose_liquidate_tx),
);
map.insert(
"donor_directed_propose_payment_tx".to_string(),
Box::new(decoder::donor_directed_propose_payment_tx),
"donor_voice_propose_payment_tx".to_string(),
Box::new(decoder::donor_voice_propose_payment_tx),
);
map.insert(
"donor_directed_propose_veto_tx".to_string(),
Box::new(decoder::donor_directed_propose_veto_tx),
"donor_voice_propose_veto_tx".to_string(),
Box::new(decoder::donor_voice_propose_veto_tx),
);
map.insert(
"donor_directed_vote_liquidation_tx".to_string(),
Box::new(decoder::donor_directed_vote_liquidation_tx),
"donor_voice_vote_liquidation_tx".to_string(),
Box::new(decoder::donor_voice_vote_liquidation_tx),
);
map.insert(
"donor_directed_vote_veto_tx".to_string(),
Box::new(decoder::donor_directed_vote_veto_tx),
"donor_voice_vote_veto_tx".to_string(),
Box::new(decoder::donor_voice_vote_veto_tx),
);
map.insert(
"jail_unjail_by_voucher".to_string(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ module diem_framework::genesis {
use ol_framework::infra_escrow;
use ol_framework::tower_state;
use ol_framework::safe;
use ol_framework::donor_directed;
use ol_framework::donor_voice;
use ol_framework::epoch_helper;
use ol_framework::burn;
use ol_framework::fee_maker;
Expand Down Expand Up @@ -145,7 +145,7 @@ module diem_framework::genesis {
slow_wallet::initialize(&diem_framework_account);
tower_state::initialize(&diem_framework_account);
safe::initialize(&diem_framework_account);
donor_directed::initialize(&diem_framework_account);
donor_voice::initialize(&diem_framework_account);
epoch_helper::initialize(&diem_framework_account);
epoch_boundary::initialize(&diem_framework_account);
burn::initialize(&diem_framework_account);
Expand Down
2 changes: 1 addition & 1 deletion framework/libra-framework/sources/ol_sources/burn.move
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/// It doesn't require any permission to be a recipient of matching funds, it's open to all (including attackers). However, this mechanism uses a market to establish which of the opt-in accounts will receive funds. And this is a simple weighting algorithm which more heavily weights toward recent donations. Evidently there are attacks possible,

// It will be costly and unpredictable (but not impossible) for attacker to close the loop, on Matching funds to themselves. It's evident that an attacker can get return on investment by re-weighting the Match Index to favor a recipient controlled by them. This is especially the case if there is low participation in the market (i.e. very few people are donating out of band).
// Mitigations: There are conditions to qualify for matching. Matching accounts must be Community Wallets, which mostly means they are a Donor Directed with multi-sig enabled. See more under donor_directed.move, but in short there is a multisig to authorize transactions, and donors to that account can vote to delay, freeze, and ultimately liquidate the donor directed account. Since the attacker can clearly own all the multisig authorities on the Donor Directed account, there is another condition which is checked for: the multisig signers cannot be related by Ancestry, meaning the attacker needs to collect conspirators from across the network graph. Lastly, any system burns (e.g. proof-of-fee) from other honest users to that account gives them governance and possibly legal claims against that wallet, there is afterall an off-chain world.
// Mitigations: There are conditions to qualify for matching. Matching accounts must be Community Wallets, which mostly means they are a Donor Directed with multi-sig enabled. See more under donor_voice.move, but in short there is a multisig to authorize transactions, and donors to that account can vote to delay, freeze, and ultimately liquidate the donor directed account. Since the attacker can clearly own all the multisig authorities on the Donor Directed account, there is another condition which is checked for: the multisig signers cannot be related by Ancestry, meaning the attacker needs to collect conspirators from across the network graph. Lastly, any system burns (e.g. proof-of-fee) from other honest users to that account gives them governance and possibly legal claims against that wallet, there is afterall an off-chain world.
// The expectation is that there is no additional overhead to honest actors, but considerable uncertainty and cost to abusers. Probabilistically there will be will some attacks or anti-social behavior. However, not all is lost: abusive behavior requires playing many other games honestly. The expectation of this experiment is that abuse is de-minimis compared to the total coin supply. As the saying goes: You can only prevent all theft if you also prevent all sales.

module ol_framework::burn {
Expand Down
Loading
Loading