Skip to content

Commit

Permalink
Release v3.2.2
Browse files Browse the repository at this point in the history
  • Loading branch information
ShadoySV authored Jul 24, 2023
2 parents 8bf5e95 + 232e2f2 commit 8c69810
Show file tree
Hide file tree
Showing 15 changed files with 386 additions and 38 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 2 additions & 5 deletions contracts/pair/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1542,12 +1542,9 @@ fn provide_liquidity_with_autostaking_to_generator() {
],
);

assert_eq!(pair.lp_token().balance(&pair.address), Uint128::new(1000));
assert_eq!(
pair.lp_token().balance(pair.address.to_string()),
Uint128::new(1000)
);
assert_eq!(
generator.query_deposit(&pair.lp_token(), astroport),
generator.query_deposit(&pair.lp_token(), &astroport),
Uint128::new(999_999000),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1423,12 +1423,9 @@ fn provide_liquidity_with_autostaking_to_generator() {
],
);

assert_eq!(pair.lp_token().balance(&pair.address), Uint128::new(1000));
assert_eq!(
pair.lp_token().balance(pair.address.to_string()),
Uint128::new(1000)
);
assert_eq!(
generator.query_deposit(&pair.lp_token(), astroport),
generator.query_deposit(&pair.lp_token(), &astroport),
Uint128::new(999_999000),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1976,12 +1976,9 @@ fn provide_liquidity_with_autostaking_to_generator() {
],
);

assert_eq!(pair.lp_token().balance(&pair.address), Uint128::new(1000));
assert_eq!(
pair.lp_token().balance(pair.address.to_string()),
Uint128::new(1000)
);
assert_eq!(
generator.query_deposit(&pair.lp_token(), astroport),
generator.query_deposit(&pair.lp_token(), &astroport),
Uint128::new(999_999000),
);
}
Expand Down
7 changes: 2 additions & 5 deletions contracts/pair_stable/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1393,12 +1393,9 @@ fn provide_liquidity_with_autostaking_to_generator() {
],
);

assert_eq!(pair.lp_token().balance(&pair.address), Uint128::new(1000));
assert_eq!(
pair.lp_token().balance(pair.address.to_string()),
Uint128::new(1000)
);
assert_eq!(
generator.query_deposit(&pair.lp_token(), astroport),
generator.query_deposit(&pair.lp_token(), &astroport),
Uint128::new(1999_999000),
);
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/tokenomics/generator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "astroport-generator"
version = "2.3.1"
version = "2.3.2"
authors = ["Astroport"]
edition = "2021"

Expand Down
247 changes: 247 additions & 0 deletions contracts/tokenomics/generator/neutron_bug_fix_log.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
* Given:

* chain_id: neutron-1

* the proposal's id that set up pools: 61 (https://app.astroport.fi/governance/proposal/61)

* the pools receiving ASTRO and their alloc points:

neutron1vw93hy8tm3xekpz9286428gesmmc8dqxmw8cujsh3fcu3rt0hvdqvlyrrl, 17739
neutron1sx99fxy4lqx0nv3ys86tkdrch82qygxyec5c8dxsk9raz4at5zpq48m66c, 38986
neutron1kmuv6zmpr2nd3fnqefcffgfmhm74c8vhyerklaphrawyp3398gws74huny, 1754
neutron1jkcf80nd4pfc2krce3xk9m9y994pllq58avx89sfzqlalej4frus27ms3a, 41521

* the total alloc point: 100000

* the ASTRO amount distributed per block, set by the proposal: 1984587

* the satellite address: neutron1ffus553eet978k024lmssw0czsxwr97mggyv85lpcsdkft8v9ufsz3sa07

* the generator address: neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny

* the vesting address: neutron178d2p84ldlzcl53clc25uy6mx3trazxdy08akhjp3qf5chlmccgq6hv2pl


* Querying the block height when the proposal was executed:
```
neutrond q wasm cs smart neutron1ffus553eet978k024lmssw0czsxwr97mggyv85lpcsdkft8v9ufsz3sa07 '{"proposal_state": {"id": 61}}' -o json | jq '.data'
1437191
```

* Checking the pools that had deposits and their last reward blocks before the proposal's execution:
```
neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"pool_info": {"lp_token": "neutron1vw93hy8tm3xekpz9286428gesmmc8dqxmw8cujsh3fcu3rt0hvdqvlyrrl"}}' --height 1437190 -o json | jq
pool not found
```

```
neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"pool_info": {"lp_token": "neutron1sx99fxy4lqx0nv3ys86tkdrch82qygxyec5c8dxsk9raz4at5zpq48m66c"}}' --height 1437190 -o json | jq '.data.last_reward_block'
488583
```

```
neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"pool_info": {"lp_token": "neutron1kmuv6zmpr2nd3fnqefcffgfmhm74c8vhyerklaphrawyp3398gws74huny"}}' --height 1437190 -o json | jq '.data.last_reward_block'
pool not found
```

```
neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"pool_info": {"lp_token": "neutron1jkcf80nd4pfc2krce3xk9m9y994pllq58avx89sfzqlalej4frus27ms3a"}}' --height 1437190 -o json | jq '.data.last_reward_block'
488583
```

* Finding the users who had deposites on the pools before the proposal's execution:
```
neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"pool_stakers": {"lp_token": "neutron1sx99fxy4lqx0nv3ys86tkdrch82qygxyec5c8dxsk9raz4at5zpq48m66c"}}' --height 1437190 -o json | jq '.data'
[
{
"account": "neutron1ryhxe5fzczelcfmrhmcw9x2jsqy677fw59fsctr09srk24lt93eszwlvyj",
"amount": "936146544918"
}
]
```

```
neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"pool_stakers": {"lp_token": "neutron1jkcf80nd4pfc2krce3xk9m9y994pllq58avx89sfzqlalej4frus27ms3a"}}' --height 1437190 -o json | jq '.data'
[
{
"account": "neutron1ryhxe5fzczelcfmrhmcw9x2jsqy677fw59fsctr09srk24lt93eszwlvyj",
"amount": "1501110150153"
}
]
```

* Checking the user's indexes now (block height 1568424 time 2023-07-18T14:59:48 at the moment of writing this):
```
key: echo "0009$(ascii_to_hex user_info)0042$(ascii_to_hex neutron1sx99fxy4lqx0nv3ys86tkdrch82qygxyec5c8dxsk9raz4at5zpq48m66c)$(ascii_to_hex neutron1ryhxe5fzczelcfmrhmcw9x2jsqy677fw59fsctr09srk24lt93eszwlvyj)"
neutrond q wasm cs raw $generator 0009757365725F696E666F00426E657574726F6E3173783939667879346C7178306E763379733836746B647263683832717967787965633563386478736B3972617A346174357A707134386D3636636E657574726F6E31727968786535667A637A656C63666D72686D63773978326A737179363737667735396673637472303973726B32346C74393365737A776C76796A --height 1568424 -o json | jq -r '.data' | base64 --decode | jq -r '.reward_user_index'
0
key: echo "0009$(ascii_to_hex user_info)0042$(ascii_to_hex neutron1jkcf80nd4pfc2krce3xk9m9y994pllq58avx89sfzqlalej4frus27ms3a)$(ascii_to_hex neutron1ryhxe5fzczelcfmrhmcw9x2jsqy677fw59fsctr09srk24lt93eszwlvyj)"
neutrond q wasm cs raw $generator 0009757365725F696E666F00426E657574726F6E316A6B636638306E6434706663326B72636533786B396D3979393934706C6C713538617678383973667A716C616C656A346672757332376D7333616E657574726F6E31727968786535667A637A656C63666D72686D63773978326A737179363737667735396673637472303973726B32346C74393365737A776C76796A --height 1568424 -o json | jq -r '.data' | base64 --decode | jq -r '.reward_user_index'
0
```

So, no rewards were withdrawn by the user at the moment

* Checking whether the user will be able to withdraw rewards before the bug fix:
```
neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"pending_token": {"lp_token": "neutron1sx99fxy4lqx0nv3ys86tkdrch82qygxyec5c8dxsk9raz4at5zpq48m66c", "user": "neutron1ryhxe5fzczelcfmrhmcw9x2jsqy677fw59fsctr09srk24lt93eszwlvyj"}}' --height 1568424
835429168530
```

```
neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"pending_token": {"lp_token": "neutron1jkcf80nd4pfc2krce3xk9m9y994pllq58avx89sfzqlalej4frus27ms3a", "user": "neutron1ryhxe5fzczelcfmrhmcw9x2jsqy677fw59fsctr09srk24lt93eszwlvyj"}}' --height 1568424
889723596667
```

available rewards on the vesting contract for the generator:
```
neutrond q wasm cs raw neutron178d2p84ldlzcl53clc25uy6mx3trazxdy08akhjp3qf5chlmccgq6hv2pl 000C76657374696E675F696E666F6E657574726F6E316A7A3538796A6179387571387A6B667739356E677976336D32776673327A6A65663976647A373564397061343666647478633573787461666E79 -o json --height 1568424 | jq -r '.data' | base64 --decode | jq
{
"schedules": [
{
"start_point": {
"time": 1689217200,
"amount": "0"
},
"end_point": {
"time": 1704942000,
"amount": "10402412000000"
}
}
],
"released_amount": "35347828690"
}
(current_time - start_time) / (end_time - start_time) * end_amount - released_amount
(1689692388 - 1689217200) / (1704942000 - 1689217200) * 10402412000000 - 35347828690 =
279002837357
```
The minimal unlocked amounts that would allow to withdraw rewards are:
```
835429168530 - 279002837357 = 556426331173
```
or
```
889723596667 - 279002837357 = 610720759310
```
unlocked amount per second by the vesting:
```
10402412000000 / (1704942000 - 1689217200) = 661530
```
So, roughly calculating, the time that we have to fix the bug is the least of the following:
```
insufficient_ASTRO / (vested amount per second * (total_alloc_point - alloc_point) / total_alloc_point) / minutes / hours / days
556426331173 / (661529 * (100000 - 38986) / 100000) / 60 / 60 / 24 = 15 days
610720759310 / (661529 * (100000 - 41521) / 100000) / 60 / 60 / 24 = 18 days
```
but the more other generator depositors claim their rewards the more time we have. The best case is that no misscomputed reward will be withdrawn until we fix the bug.
* Querying virtual amounts that the user had on the moment of the proposal execution:
```
neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"user_virtual_amount": {"lp_token": "neutron1sx99fxy4lqx0nv3ys86tkdrch82qygxyec5c8dxsk9raz4at5zpq48m66c", "user": "neutron1ryhxe5fzczelcfmrhmcw9x2jsqy677fw59fsctr09srk24lt93eszwlvyj"}}' --height 1437191

374458617967

neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"user_virtual_amount": {"lp_token": "neutron1jkcf80nd4pfc2krce3xk9m9y994pllq58avx89sfzqlalej4frus27ms3a", "user": "neutron1ryhxe5fzczelcfmrhmcw9x2jsqy677fw59fsctr09srk24lt93eszwlvyj"}}' --height 1437191

600444060061
```
* The solution to fix misscomputed rewards is to increase the user reward indexes on contract migration as it follows below:
* query the current user reward indexes for those pools
* increase them by the following calculated indexes:
```
(setup_pools_block - the wrong last reward block) * tokens_per_block * alloc_point / total_alloc_point / user's virtual amount
(1437191 - 488583) * 1984587 * 38986 / 100000 / 374458617967 = 1.96002573416386269210
(1437191 - 488583) * 1984587 * 41521 / 100000 / 600444060061 = 1.30182370931349860257
```
* Checking rewards if the fix would apply now:
* query last reward block and calculate the current pool's global index:
```
neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"pool_info": {"lp_token": "neutron1sx99fxy4lqx0nv3ys86tkdrch82qygxyec5c8dxsk9raz4at5zpq48m66c"}}' --height 1568424 -o json | jq -r '.data.global_reward_index, .data.last_reward_block'
2.225500979661236903
1565741
neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"total_virtual_supply": {"generator": "neutron1sx99fxy4lqx0nv3ys86tkdrch82qygxyec5c8dxsk9raz4at5zpq48m66c"}}' --height 1568424 -o json | jq -r '.data'
375311882818
last_global_index + (current_block - last_reward_block) * astro_per_block * alloc_point / total_alloc_point / virtual_supply
2.225500979661236903 + (1568424 - 1565741) * 1984587 * 38986 / 100000 / 375311882818 = 2.23103202448996594742
```
```
neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"pool_info": {"lp_token": "neutron1jkcf80nd4pfc2krce3xk9m9y994pllq58avx89sfzqlalej4frus27ms3a"}}' --height 1568424 -o json | jq -r '.data.global_reward_index, .data.last_reward_block'
1.481537641504742878
1568250
neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"total_virtual_supply": {"generator": "neutron1jkcf80nd4pfc2krce3xk9m9y994pllq58avx89sfzqlalej4frus27ms3a"}}' --height 1568424 -o json | jq -r '.data'
601532655696
last_global_index + (current_block - last_reward_block) * astro_per_block * alloc_point / total_alloc_point / virtual_supply
1.481537641504742878 + (1568424 - 1568250) * 1984587 * 41521 / 100000 / 601532655696 = 1.48177599854607936786
```
* query virtual amounts that the user has now:
```
neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"user_virtual_amount": {"lp_token": "neutron1sx99fxy4lqx0nv3ys86tkdrch82qygxyec5c8dxsk9raz4at5zpq48m66c", "user": "neutron1ryhxe5fzczelcfmrhmcw9x2jsqy677fw59fsctr09srk24lt93eszwlvyj"}}' --height 1568424
374458617967
neutrond q wasm cs smart neutron1jz58yjay8uq8zkfw95ngyv3m2wfs2zjef9vdz75d9pa46fdtxc5sxtafny '{"user_virtual_amount": {"lp_token": "neutron1jkcf80nd4pfc2krce3xk9m9y994pllq58avx89sfzqlalej4frus27ms3a", "user": "neutron1ryhxe5fzczelcfmrhmcw9x2jsqy677fw59fsctr09srk24lt93eszwlvyj"}}' --height 1568424
600444060061
```
* calculate reward by indexes:
(global_reward_index - user_reward_index) * deposit
```
(2.23103202448996594742 - 1.96002573416386269210) * 374458617967 = 101480640935
(1.48177599854607936786 - 1.30182370931349860257) * 600444060061 = 108051283164
```
* calculate reward by blocks:
(current_block - proposal_block) * astro_per_block * alloc_point / total_alloc_point
```
(1568424 - 1437191) * 1984587 * 38986 / 100000 = 101536427187
(1568424 - 1437191) * 1984587 * 41521 / 100000 = 108138664989
```
* rewards by indexes is a bit less, because of rounding issues that occurs by not using those exact types that used in the contract
12 changes: 10 additions & 2 deletions contracts/tokenomics/generator/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,10 @@ pub fn execute_setup_pools(
mass_update_pools(deps.branch(), &env, &cfg, &prev_pools)?;

for (lp_token, _) in &setup_pools {
if !POOL_INFO.has(deps.storage, lp_token) {
if let Some(mut pool_info) = POOL_INFO.may_load(deps.storage, lp_token)? {
pool_info.last_reward_block = cfg.start_block.max(env.block.height.into());
POOL_INFO.save(deps.storage, lp_token, &pool_info)?;
} else {
create_pool(deps.branch(), &env, lp_token, &cfg)?;
}
}
Expand Down Expand Up @@ -2037,7 +2040,12 @@ pub fn migrate(mut deps: DepsMut, env: Env, msg: MigrateMsg) -> Result<Response,
"2.2.0" | "2.2.0+togrb" => {
migration::migrate_configs_from_v220(&mut deps, &msg)?;
}
"2.3.0" => {}
"2.3.0" => {
if env.block.chain_id == "neutron-1" {
migration::fix_neutron_users_reward_indexes(&mut deps)?;
}
}
"2.3.1" => {}
_ => return Err(ContractError::MigrationError {}),
},
_ => return Err(ContractError::MigrationError {}),
Expand Down
28 changes: 26 additions & 2 deletions contracts/tokenomics/generator/src/migration.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::state::CONFIG;
use crate::state::{CONFIG, USER_INFO};
use astroport::asset::AssetInfo;

use astroport::generator::{Config, MigrateMsg};
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Addr, DepsMut, StdResult, Uint128, Uint64};
use cosmwasm_std::{Addr, Decimal, DepsMut, StdError, StdResult, Uint128, Uint64};
use cw_storage_plus::Item;

/// This structure stores the core parameters for the Generator contract.
Expand Down Expand Up @@ -67,3 +67,27 @@ pub fn migrate_configs_from_v220(deps: &mut DepsMut, msg: &MigrateMsg) -> StdRes

CONFIG.save(deps.storage, &cfg)
}

pub fn fix_neutron_users_reward_indexes(deps: &mut DepsMut) -> StdResult<()> {
let pool1 =
Addr::unchecked("neutron1sx99fxy4lqx0nv3ys86tkdrch82qygxyec5c8dxsk9raz4at5zpq48m66c");
let pool2 =
Addr::unchecked("neutron1jkcf80nd4pfc2krce3xk9m9y994pllq58avx89sfzqlalej4frus27ms3a");

let depositor =
Addr::unchecked("neutron1ryhxe5fzczelcfmrhmcw9x2jsqy677fw59fsctr09srk24lt93eszwlvyj");

// We already know that the new user info structure is used and that the values of that type exist there
USER_INFO.update::<_, StdError>(deps.storage, (&pool1, &depositor), |v| {
let mut r = v.unwrap();
r.reward_user_index += Decimal::raw(1960025734161847622);
Ok(r)
})?;
USER_INFO.update::<_, StdError>(deps.storage, (&pool2, &depositor), |v| {
let mut r = v.unwrap();
r.reward_user_index += Decimal::raw(1301823709312052739);
Ok(r)
})?;

Ok(())
}
Loading

0 comments on commit 8c69810

Please sign in to comment.