From 5890ef8aa2fa4d5f7b774a9272cf68fd23cb4e6e Mon Sep 17 00:00:00 2001 From: Murisi Tarusenga Date: Thu, 22 Feb 2024 18:35:50 +0200 Subject: [PATCH] Simplified the reward distribution algorithm. --- crates/shielded_token/src/conversion.rs | 143 +++++++++--------------- crates/tests/src/integration/masp.rs | 36 +++--- wasm/checksums.json | 48 ++++---- 3 files changed, 96 insertions(+), 131 deletions(-) diff --git a/crates/shielded_token/src/conversion.rs b/crates/shielded_token/src/conversion.rs index 23db438d42..e1b7980ed1 100644 --- a/crates/shielded_token/src/conversion.rs +++ b/crates/shielded_token/src/conversion.rs @@ -293,6 +293,24 @@ where .normed_inflation .get_or_insert(ref_inflation); + if *token == native_token { + // Save the new normed inflation + *normed_inflation += (((Uint::from(*normed_inflation) + * Uint::from(reward.0)) + + Uint::from(reward.1 - 1)) + / reward.1) + .try_into() + .unwrap_or_else(|_| { + tracing::warn!( + "MASP reward for {} assumed to be 0 because the \ + computed value is too large. Please check the \ + inflation parameters.", + token + ); + 0u128 + }); + } + for digit in MaspDigitPos::iter() { // Provide an allowed conversion from previous timestamp. The // negative sign allows each instance of the old asset to be @@ -311,97 +329,44 @@ where Some(wl_storage.storage.block.epoch), ) .into_storage_result()?; - if *token == native_token { - // The amount that will be given of the new native token for - // every amount of the native token given in the - // previous epoch - let new_normed_inflation = Uint::from(*normed_inflation) - .checked_add( - (Uint::from(*normed_inflation) * Uint::from(reward.0)) - / reward.1, - ) - .and_then(|x| x.try_into().ok()) - .unwrap_or_else(|| { - tracing::warn!( - "MASP reward for {} assumed to be 0 because the \ - computed value is too large. Please check the \ - inflation parameters.", - token - ); - *normed_inflation - }); - // The conversion is computed such that if consecutive - // conversions are added together, the - // intermediate native tokens cancel/ - // telescope out - current_convs.insert( - (token.clone(), denom, digit), - (MaspAmount::from_pair( - old_asset, - -(*normed_inflation as i128), - ) + + // Express the inflation reward in real terms, that is, with + // respect to the native asset in the zeroth + // epoch + let real_reward = ((Uint::from(reward.0) + * Uint::from(ref_inflation)) + / *normed_inflation) + .try_into() + .unwrap_or_else(|_| { + tracing::warn!( + "MASP reward for {} assumed to be 0 because the \ + computed value is too large. Please check the \ + inflation parameters.", + token + ); + 0u128 + }); + // The conversion is computed such that if consecutive + // conversions are added together, the + // intermediate tokens cancel/ telescope out + current_convs.insert( + (token.clone(), denom, digit), + (MaspAmount::from_pair(old_asset, -(reward.1 as i128)) .unwrap() - + MaspAmount::from_pair( - new_asset, - new_normed_inflation as i128, - ) - .unwrap()) - .into(), - ); - // Operations that happen exactly once for each token - if digit == MaspDigitPos::Three { - // The reward for each reward.1 units of the current asset - // is reward.0 units of the reward token - let native_reward = - addr_bal * (new_normed_inflation, *normed_inflation); - total_reward += native_reward - .0 - .checked_add(native_reward.1) - .unwrap_or(Amount::max()) - .checked_sub(addr_bal) - .unwrap_or_default(); - // Save the new normed inflation - *normed_inflation = new_normed_inflation; - } - } else { - // Express the inflation reward in real terms, that is, with - // respect to the native asset in the zeroth - // epoch - let real_reward = ((Uint::from(reward.0) - * Uint::from(ref_inflation)) - / *normed_inflation) - .try_into() - .unwrap_or_else(|_| { - tracing::warn!( - "MASP reward for {} assumed to be 0 because the \ - computed value is too large. Please check the \ - inflation parameters.", - token - ); - 0u128 - }); - // The conversion is computed such that if consecutive - // conversions are added together, the - // intermediate tokens cancel/ telescope out - current_convs.insert( - (token.clone(), denom, digit), - (MaspAmount::from_pair(old_asset, -(reward.1 as i128)) + + MaspAmount::from_pair(new_asset, reward.1 as i128) .unwrap() - + MaspAmount::from_pair(new_asset, reward.1 as i128) - .unwrap() - + MaspAmount::from_pair( - reward_assets[digit as usize], - real_reward as i128, - ) - .unwrap()) - .into(), - ); - // Operations that happen exactly once for each token - if digit == MaspDigitPos::Three { - // The reward for each reward.1 units of the current asset - // is reward.0 units of the reward token - total_reward += (addr_bal * (reward.0, reward.1)).0; - } + + MaspAmount::from_pair( + reward_assets[digit as usize], + real_reward as i128, + ) + .unwrap()) + .into(), + ); + // Operations that happen exactly once for each token + if digit == MaspDigitPos::Three { + // The reward for each reward.1 units of the current asset + // is reward.0 units of the reward token + total_reward += (addr_bal * (reward.0, reward.1)).0; } // Add a conversion from the previous asset type wl_storage.storage.conversion_state.assets.insert( diff --git a/crates/tests/src/integration/masp.rs b/crates/tests/src/integration/masp.rs index deef3c1061..f8f1071bd2 100644 --- a/crates/tests/src/integration/masp.rs +++ b/crates/tests/src/integration/masp.rs @@ -194,7 +194,7 @@ fn masp_incentives() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 0.09292")); + assert!(captured.contains("nam: 0.092828")); // Assert NAM balance at MASP pool is exclusively the // rewards from the shielded BTC @@ -317,7 +317,7 @@ fn masp_incentives() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 0.359578")); + assert!(captured.contains("nam: 0.357917")); // Assert NAM balance at MASP pool is an accumulation of // rewards from both the shielded BTC and shielded ETH @@ -337,7 +337,7 @@ fn masp_incentives() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 0.671183")); + assert!(captured.contains("nam: 0.671201")); // Wait till epoch boundary node.next_epoch(); @@ -403,7 +403,7 @@ fn masp_incentives() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 0.719514")); + assert!(captured.contains("nam: 0.715164")); node.next_epoch(); @@ -425,7 +425,7 @@ fn masp_incentives() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 1.58943")); + assert!(captured.contains("nam: 1.589461")); // Wait till epoch boundary node.next_epoch(); @@ -488,7 +488,7 @@ fn masp_incentives() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 1.113911")); + assert!(captured.contains("nam: 1.107819")); // Assert NAM balance at MASP pool is // the accumulation of rewards from the shielded assets (BTC and ETH) @@ -508,7 +508,7 @@ fn masp_incentives() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 1.83743")); + assert!(captured.contains("nam: 1.837461")); // Wait till epoch boundary node.next_epoch(); @@ -532,7 +532,7 @@ fn masp_incentives() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 1.113911")); + assert!(captured.contains("nam: 1.107819")); // Assert NAM balance at VK(B) is the rewards dispensed earlier // (since VK(A) has no shielded assets, no further rewards should @@ -553,7 +553,7 @@ fn masp_incentives() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 0.719514")); + assert!(captured.contains("nam: 0.715164")); // Assert NAM balance at MASP pool is // the accumulation of rewards from the shielded assets (BTC and ETH) @@ -573,7 +573,7 @@ fn masp_incentives() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 1.83743")); + assert!(captured.contains("nam: 1.837461")); // Wait till epoch boundary to prevent conversion expiry during transaction // construction @@ -592,7 +592,7 @@ fn masp_incentives() -> Result<()> { "--token", NAM, "--amount", - "0.719514", + "0.715164", "--signing-keys", BERTHA_KEY, "--node", @@ -617,7 +617,7 @@ fn masp_incentives() -> Result<()> { "--token", NAM, "--amount", - "1.113911", + "1.107819", "--signing-keys", ALBERT_KEY, "--node", @@ -681,7 +681,7 @@ fn masp_incentives() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 0.004005")); + assert!(captured.contains("nam: 0.014478")); Ok(()) } @@ -1661,7 +1661,7 @@ fn dynamic_assets() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 0.0303")); + assert!(captured.contains("nam: 0.03027")); // Assert BTC balance at VK(A) is still 2 let captured = CapturedOutput::of(|| { @@ -1732,7 +1732,7 @@ fn dynamic_assets() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 0.07575")); + assert!(captured.contains("nam: 0.075675")); { // Stop decoding and distributing shielded rewards for BTC in next epoch @@ -1779,7 +1779,7 @@ fn dynamic_assets() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 0.07575")); + assert!(captured.contains("nam: 0.075675")); // Wait till epoch boundary node.next_epoch(); @@ -1820,7 +1820,7 @@ fn dynamic_assets() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 0.07575")); + assert!(captured.contains("nam: 0.075675")); { // Start distributing shielded rewards for NAM in next epoch @@ -1872,7 +1872,7 @@ fn dynamic_assets() -> Result<()> { ) }); assert!(captured.result.is_ok()); - assert!(captured.contains("nam: 0.075825")); + assert!(captured.contains("nam: 0.075675")); Ok(()) } diff --git a/wasm/checksums.json b/wasm/checksums.json index 9825650b0b..faa905c304 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,26 +1,26 @@ { - "tx_become_validator.wasm": "tx_become_validator.8151595cbc63dd98da8e9242fe5c74ad197615139bde86deb76f5a82eaf5cbe4.wasm", - "tx_bond.wasm": "tx_bond.f5f51dbd9210a11a9af10895b3b1778937c2338d0b05321e628971c357845786.wasm", - "tx_bridge_pool.wasm": "tx_bridge_pool.d570eae9213c283c5d2ea161674dfde0f3a6dc1d1c7eed27c3c765c0a0ec9ed2.wasm", - "tx_change_consensus_key.wasm": "tx_change_consensus_key.62c1429e513fa0fa4e8c235b26fef4d3f0b4921fc98cec10e5e1ffcc516ca851.wasm", - "tx_change_validator_commission.wasm": "tx_change_validator_commission.b841e3db62d0982d929dee5ed382105952dc658b5120da3d6b74e3610594272b.wasm", - "tx_change_validator_metadata.wasm": "tx_change_validator_metadata.6c40ef29b37de7fe0d6cf51c51ac0f29d5a5cc767466acdda8e4793f421e2932.wasm", - "tx_claim_rewards.wasm": "tx_claim_rewards.d01907535a68bafa2a8962dce033ee34998eddf5fc091bff888022df58cb184b.wasm", - "tx_deactivate_validator.wasm": "tx_deactivate_validator.8c56c3e6a59f6e663db4aa38a8c4a9d64d98d57c061db62b8f3330562cc487b1.wasm", - "tx_ibc.wasm": "tx_ibc.5050d1f0cf8ee45ddef5b13fc59fb7215d03fe8001724416fc46e307475a2d2d.wasm", - "tx_init_account.wasm": "tx_init_account.4de8ce9ca014f3d73074062776b17b4db906eefacc0e8507d7860beb0f8561b2.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.7ea60ada35b2e323e1835d07ad86be591b999257dd9b8d9f4a3361cb6f735780.wasm", - "tx_reactivate_validator.wasm": "tx_reactivate_validator.c5b959fa1a32ef16d2bc2fe8c8b046300a5b2b007f313f5e42873f98072e7840.wasm", - "tx_redelegate.wasm": "tx_redelegate.f27a966d2c9b8f10d24516396bf1504f1137d6f3fc56f2da8231a50618dfbafa.wasm", - "tx_resign_steward.wasm": "tx_resign_steward.c2cc8f8597720c6d4e2c0dc3688870f681c416819b5e923e79f8daf08918aa9d.wasm", - "tx_reveal_pk.wasm": "tx_reveal_pk.8f36c126b97e0bdceaab2eeff1b7232528b6a04bc7b994e19490fe55b27f2879.wasm", - "tx_transfer.wasm": "tx_transfer.a0e53e0968896e05abe5b82bf3d75984b5761fe297ec6a850a7a59e98e6711bc.wasm", - "tx_unbond.wasm": "tx_unbond.ad0f542be4f7dd54f90b575dba89a1dcf7e6140e18a8750a379213a6a2b24dee.wasm", - "tx_unjail_validator.wasm": "tx_unjail_validator.a4ec69c7debeaa5bfda466750490f11da07555de87cf79819cdbf1e19e896789.wasm", - "tx_update_account.wasm": "tx_update_account.7aedd91e8b4423ae41d203322deae7b4a9edb453d0eb0e3e35b3b5d057b12a5a.wasm", - "tx_update_steward_commission.wasm": "tx_update_steward_commission.6fa736ac072bf27b5ea8e1ad1270b71b33b9cbfe06b19ca5f5dd0dcbe88606c2.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.c66250b350d07701d08c903ed219f649a4794067efd76c6af8a872d0a5cdec7e.wasm", - "tx_withdraw.wasm": "tx_withdraw.0c359816f375aaedf85cca4ae4c33e9e40e6c5c20713a2b7a223a3fb1dab59af.wasm", - "vp_implicit.wasm": "vp_implicit.6279e39412240f27d68df76364d1fabe10c11a2995d1a9baea6e9d39daa6e90e.wasm", - "vp_user.wasm": "vp_user.15c520832cbe6e48c4284017d6f4c48c4b7fa63e5ebd7f94846df2692b248af6.wasm" + "tx_become_validator.wasm": "tx_become_validator.7ecf1a5713a60738cffc4d5bed3ef78dca6b51fc120b324454324c82185e8cb0.wasm", + "tx_bond.wasm": "tx_bond.65a9c927b5d6bd27f7425d5d2e7f53e599b3773cd6927e26e477dc3247a43318.wasm", + "tx_bridge_pool.wasm": "tx_bridge_pool.d59eca9c9bb66a06cb30f41f69f0daacde4b2de9fd7cc9df9785b2e844e76c6a.wasm", + "tx_change_consensus_key.wasm": "tx_change_consensus_key.9a018e950da16049a6cebfee3cbdafee9895c94956033a26bb177bcb7eb0b43d.wasm", + "tx_change_validator_commission.wasm": "tx_change_validator_commission.0588cd391911b5782b9e408e3f3356937021b314ec018942d6b942b1e2b8a15f.wasm", + "tx_change_validator_metadata.wasm": "tx_change_validator_metadata.1ac64bcbb70a1b2f4001ed536bdf52e3e1e8ac0ec1b5ede8c15b74035d5fee16.wasm", + "tx_claim_rewards.wasm": "tx_claim_rewards.772f77ed6d683e9f847cd707c240f2c520e631c90e425f90d621af1ece03a9d7.wasm", + "tx_deactivate_validator.wasm": "tx_deactivate_validator.a39d600a514d1589910d7391a2b30aadd55426ea7e34ec6f56a4109f865c9cf8.wasm", + "tx_ibc.wasm": "tx_ibc.c039f4259a2a4af397ad29b2dfe0da91eb786d7621489145b853f28e77ac4ea4.wasm", + "tx_init_account.wasm": "tx_init_account.b96acf629bd5c1bc4c508a45eaca4d6a177da9b45b0c79f12f118194577a8e48.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.74d010a48e6729bf9d982f3ed44308c3f17b465a72ce9af07e40029152feb64d.wasm", + "tx_reactivate_validator.wasm": "tx_reactivate_validator.1e2ac7586174181f5ac7dc5777c590aef64dc93a074a39883f2d71c13b07c517.wasm", + "tx_redelegate.wasm": "tx_redelegate.9fae350b11ea59116da874c2b40e8fdcc211d290ed38441be4ceb6e87ddd790d.wasm", + "tx_resign_steward.wasm": "tx_resign_steward.5f07146ff46c57f56ccfe10103295abed999ad45b3036757a5d463a9426fadc7.wasm", + "tx_reveal_pk.wasm": "tx_reveal_pk.7de9d2db5206a137c59f8154ea151fa7779a9ac1c0ff6ccd629642b43f9b8872.wasm", + "tx_transfer.wasm": "tx_transfer.6add73a2a8c4853e03dc94041af0c28f1b574ad42d9cce698344a52a9fae3f4d.wasm", + "tx_unbond.wasm": "tx_unbond.3a09ac687a924de125737b386736fa1945095cd5e29c2ab05963b6d391d1d7e4.wasm", + "tx_unjail_validator.wasm": "tx_unjail_validator.3c3045eee4a449065b5791cd0f09ccf09b731b4f5964a8dbafe4b3d38a6deb49.wasm", + "tx_update_account.wasm": "tx_update_account.a65464e907fd3cf3cadbf2042b19f0a42e2a8379495b02ce5ad1e6de0b7264d5.wasm", + "tx_update_steward_commission.wasm": "tx_update_steward_commission.cd559ad1c8bfef54c66cc0a59e7c165c43ddf29656c8f43bcc69b4435cda89dc.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.9aaca04a950561cb68c7d08f6f59f6a032aabbda1c2ba6c1b5b0e205bb9897c8.wasm", + "tx_withdraw.wasm": "tx_withdraw.f99fc834aba96d2082815839a22d1ef4d1b38aacc4808b5a7f58e1c37306dcb0.wasm", + "vp_implicit.wasm": "vp_implicit.5b800b7d94420ffbe46ba6dfa0f205a230c2eeb18208ec0a25c3403974666521.wasm", + "vp_user.wasm": "vp_user.1dfdde2b7d9c4d18e8294ec7b8f674b9f8b0691fb4f8ba2a61f41bed673f4ef4.wasm" } \ No newline at end of file