diff --git a/.changelog/unreleased/bug-fixes/135-do-not-insert-props-into-props-by-score-on-creation.md b/.changelog/unreleased/bug-fixes/135-do-not-insert-props-into-props-by-score-on-creation.md new file mode 100644 index 00000000..a797b403 --- /dev/null +++ b/.changelog/unreleased/bug-fixes/135-do-not-insert-props-into-props-by-score-on-creation.md @@ -0,0 +1,2 @@ +- fix: do not insert proposal into PROPS_BY_SCORE on proposal creation. + ([\#135](https://github.com/informalsystems/hydro/pull/135)) diff --git a/artifacts/checksums.txt b/artifacts/checksums.txt index 90d044ff..01ff71fc 100644 --- a/artifacts/checksums.txt +++ b/artifacts/checksums.txt @@ -1,2 +1,2 @@ -42675f222ce57123a53125584f18220e18566bc16aabaa75deb8043ea95c9bda hydro.wasm +8291920f2b3b1c9916886b4bd97119fa7783cff0240a1612a217acadfe1239e2 hydro.wasm b522862cb198bbfa2cab046110b4d26a590dea315fe838af3cf1455cad41f9b7 tribute.wasm diff --git a/artifacts/hydro.wasm b/artifacts/hydro.wasm index d330027a..40c09216 100644 Binary files a/artifacts/hydro.wasm and b/artifacts/hydro.wasm differ diff --git a/contracts/hydro/src/contract.rs b/contracts/hydro/src/contract.rs index 18af3d78..5506c712 100644 --- a/contracts/hydro/src/contract.rs +++ b/contracts/hydro/src/contract.rs @@ -558,12 +558,6 @@ fn create_proposal( PROP_ID.save(deps.storage, &(proposal_id + 1))?; PROPOSAL_MAP.save(deps.storage, (round_id, tranche_id, proposal_id), &proposal)?; - PROPS_BY_SCORE.save( - deps.storage, - ((round_id, tranche_id), proposal.power.into(), proposal_id), - &proposal_id, - )?; - Ok(Response::new() .add_attribute("action", "create_proposal") .add_attribute("sender", info.sender) diff --git a/contracts/hydro/src/testing.rs b/contracts/hydro/src/testing.rs index 43900aed..830b8c0b 100644 --- a/contracts/hydro/src/testing.rs +++ b/contracts/hydro/src/testing.rs @@ -333,20 +333,19 @@ fn create_proposal_basic_test() { let proposal = &res.proposals[0]; assert_eq!(expected_round_id, proposal.round_id); + assert_eq!(0, proposal.power.u128()); let proposal = &res.proposals[1]; assert_eq!(expected_round_id, proposal.round_id); + assert_eq!(0, proposal.power.u128()); + // assert that the proposals are not added to top N proposals + // immediately upon creation, as their voting power is 0 let res = query_top_n_proposals(deps.as_ref(), expected_round_id, 1, 2); assert!(res.is_ok(), "error: {:?}", res); let res = res.unwrap(); - assert_eq!(2, res.proposals.len()); - - // check that both proposals have power 0 - for proposal in res.proposals.iter() { - assert_eq!(0, proposal.power.u128()); - } + assert_eq!(0, res.proposals.len()); } #[test] diff --git a/contracts/hydro/src/testing_lsm_integration.rs b/contracts/hydro/src/testing_lsm_integration.rs index a2f15982..a400973a 100644 --- a/contracts/hydro/src/testing_lsm_integration.rs +++ b/contracts/hydro/src/testing_lsm_integration.rs @@ -13,7 +13,7 @@ use neutron_sdk::{ use neutron_std::types::ibc::applications::transfer::v1::QueryDenomTraceResponse; use crate::{ - contract::{execute, instantiate, query_top_n_proposals, sudo}, + contract::{execute, instantiate, query_round_tranche_proposals, query_top_n_proposals, sudo}, lsm_integration::{ get_total_power_for_round, get_validator_power_ratio_for_round, update_scores_due_to_power_ratio_change, validate_denom, @@ -699,7 +699,7 @@ fn lock_tokens_multiple_validators_and_vote() { // check proposals { // Check the proposal scores - let proposals = query_top_n_proposals(deps.as_ref(), 0, 1, 2); + let proposals = query_round_tranche_proposals(deps.as_ref(), 0, 1, 0, 100); // unwrap the proposals let proposals = proposals.unwrap(); diff --git a/test/interchain/hydro_test.go b/test/interchain/hydro_test.go index 20549720..5bf57bff 100644 --- a/test/interchain/hydro_test.go +++ b/test/interchain/hydro_test.go @@ -234,9 +234,9 @@ func (s *HydroSuite) TestActiveValidatorChange() { err = s.LockTokens(0, 3*86400000000000, "10", dstIbcDenom2, contractAddr) s.Require().NoError(err) - votingPowerVal1Val1 := "10" - votingPowerVal1Val2 := "25" - votingPowerVal1Val3 := "30" + votingPowerVal1Denom := "10" + votingPowerVal1Val2Denoms := "25" + votingPowerVal1Val3Denoms := "30" // create hydro proposals log.Println("==== Creating proposals") @@ -253,7 +253,7 @@ func (s *HydroSuite) TestActiveValidatorChange() { s.Require().NoError(err) proposal, err = s.GetProposalByTitle(contractAddr, "tranche 1 prop 1", 1) s.Require().NoError(err) - s.Require().Equal(votingPowerVal1Val2, proposal.Power) + s.Require().Equal(votingPowerVal1Val2Denoms, proposal.Power) // increase stake for val3 on hub, so that val2 drops from active valset and val3 enters log.Println("==== Increasing stake for val3 to drop val2 from active valset") @@ -263,23 +263,20 @@ func (s *HydroSuite) TestActiveValidatorChange() { log.Println("==== Registering interchain query for val3") s.RegisterInterchainQueries([]string{s.HubChain.ValidatorWallets[2].ValoperAddress}, contractAddr, s.NeutronChain.ValidatorWallets[0].Moniker) - // lock token for val3 - log.Println("==== Locking tokens for val3") - err = s.LockTokens(0, 6*86400000000000, "10", dstIbcDenom3, contractAddr) - s.Require().NoError(err) - // check that voting power is equal to voting power of val1 because val2 is not among active vals anymore proposal, err = s.GetProposalByTitle(contractAddr, "tranche 1 prop 1", 1) s.Require().NoError(err) - s.Require().Equal(votingPowerVal1Val1, proposal.Power) + s.Require().Equal(votingPowerVal1Denom, proposal.Power) - // vote again so that val3 power is taken into account - log.Println("==== Voting for proposal with val3 shares") - err = s.VoteForHydroProposal(0, contractAddr, proposal.ProposalID, 1) + // lock token for val3 + log.Println("==== Locking tokens for val3") + err = s.LockTokens(0, 6*86400000000000, "10", dstIbcDenom3, contractAddr) s.Require().NoError(err) + + // proposal power is increased with val3 shares right after the locking proposal, err = s.GetProposalByTitle(contractAddr, "tranche 1 prop 1", 1) s.Require().NoError(err) - s.Require().Equal(votingPowerVal1Val3, proposal.Power) + s.Require().Equal(votingPowerVal1Val3Denoms, proposal.Power) } // TestValidatorSlashing tests that voting power of user, proposal, round is changed after validator is slashed @@ -507,8 +504,8 @@ func (s *HydroSuite) TestTributeContract() { // proposal power after voting: proposal_1=800, proposal_2: 400, proposal_3: 200, proposal_4: 0 // proposal 1 and 2 are in top N proposals(N=2), which means that only those voters got the tribute reward and tribute from the other proposals can be refunded - s.Require().True(newBalanceVal2.Sub(oldBalanceVal2).Equal(math.NewInt(9000))) // reward is tribute for proposal1 - communityTax = 10000-10%=9000 - s.Require().True(newBalanceVal3.Sub(oldBalanceVal3).Equal(math.NewInt(18000))) // reward is tribute for proposal2 - communityTax = 20000-10%=18000 + s.Require().True(newBalanceVal2.Sub(oldBalanceVal2).Equal(math.NewInt(10000))) // reward is tribute for proposal1 = 10000 + s.Require().True(newBalanceVal3.Sub(oldBalanceVal3).Equal(math.NewInt(20000))) // reward is tribute for proposal2 = 20000 s.Require().True(newBalanceVal1.GT(oldBalanceVal1)) // refunded proposal3 s.Require().True(newBalanceVal4.GT(oldBalanceVal4)) // refunded proposal4 }