From 0b7a416eb282bb1d68b2484054e402fc5b60f10e Mon Sep 17 00:00:00 2001 From: Kerber0x Date: Fri, 14 Jun 2024 12:21:17 +0100 Subject: [PATCH] chore: change whitelist api --- .../alliance-hub/schema/alliance-hub.json | 424 ++++++++++++++---- .../alliance-hub/schema/raw/execute.json | 94 +--- .../raw/response_to_all_staked_balances.json | 110 ++++- .../raw/response_to_staked_balance.json | 110 ++++- .../response_to_total_staked_balances.json | 110 ++++- contracts/alliance-hub/src/contract.rs | 4 + contracts/alliance-hub/src/migrations.rs | 2 +- contracts/alliance-hub/src/tests/assets.rs | 53 ++- contracts/alliance-hub/src/tests/helpers.rs | 10 +- contracts/alliance-hub/src/tests/rewards.rs | 34 +- .../alliance-hub/src/tests/stake_unstake.rs | 60 ++- 11 files changed, 790 insertions(+), 221 deletions(-) diff --git a/contracts/alliance-hub/schema/alliance-hub.json b/contracts/alliance-hub/schema/alliance-hub.json index 5cf280c..c3638fb 100644 --- a/contracts/alliance-hub/schema/alliance-hub.json +++ b/contracts/alliance-hub/schema/alliance-hub.json @@ -169,7 +169,7 @@ "additionalProperties": { "type": "array", "items": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" + "$ref": "#/definitions/AssetInfoWithConfig" } } } @@ -450,22 +450,6 @@ }, "additionalProperties": false }, - "AssetConfig": { - "type": "object", - "required": [ - "stake_config", - "yearly_take_rate" - ], - "properties": { - "stake_config": { - "$ref": "#/definitions/StakeConfig" - }, - "yearly_take_rate": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, "AssetDistribution": { "type": "object", "required": [ @@ -517,18 +501,18 @@ "info" ], "properties": { - "config": { + "info": { + "$ref": "#/definitions/AssetInfoBase_for_Addr" + }, + "yearly_take_rate": { "anyOf": [ { - "$ref": "#/definitions/AssetConfig" + "$ref": "#/definitions/Decimal" }, { "type": "null" } ] - }, - "info": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" } }, "additionalProperties": false @@ -562,72 +546,6 @@ "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", "type": "string" }, - "StakeConfig": { - "oneOf": [ - { - "type": "string", - "enum": [ - "default" - ] - }, - { - "type": "object", - "required": [ - "astroport" - ], - "properties": { - "astroport": { - "type": "object", - "required": [ - "contract", - "reward_infos" - ], - "properties": { - "contract": { - "$ref": "#/definitions/Addr" - }, - "reward_infos": { - "type": "array", - "items": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "ve3" - ], - "properties": { - "ve3": { - "type": "object", - "required": [ - "contract", - "reward_infos" - ], - "properties": { - "contract": { - "$ref": "#/definitions/Addr" - }, - "reward_infos": { - "type": "array", - "items": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, "Uint128": { "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", "type": "string" @@ -910,6 +828,36 @@ "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", "type": "string" }, + "AssetConfigRuntime": { + "type": "object", + "required": [ + "harvested", + "last_taken_s", + "stake_config", + "taken", + "yearly_take_rate" + ], + "properties": { + "harvested": { + "$ref": "#/definitions/Uint128" + }, + "last_taken_s": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "stake_config": { + "$ref": "#/definitions/StakeConfig" + }, + "taken": { + "$ref": "#/definitions/Uint128" + }, + "yearly_take_rate": { + "$ref": "#/definitions/Decimal" + } + }, + "additionalProperties": false + }, "AssetInfoBase_for_Addr": { "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", "oneOf": [ @@ -939,11 +887,83 @@ } ] }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "StakeConfig": { + "oneOf": [ + { + "type": "string", + "enum": [ + "default" + ] + }, + { + "type": "object", + "required": [ + "astroport" + ], + "properties": { + "astroport": { + "type": "object", + "required": [ + "contract", + "reward_infos" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + }, + "reward_infos": { + "type": "array", + "items": { + "$ref": "#/definitions/AssetInfoBase_for_Addr" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ve3" + ], + "properties": { + "ve3": { + "type": "object", + "required": [ + "contract", + "reward_infos" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + }, + "reward_infos": { + "type": "array", + "items": { + "$ref": "#/definitions/AssetInfoBase_for_Addr" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, "StakedBalanceRes": { "type": "object", "required": [ "asset", - "balance" + "balance", + "config", + "shares" ], "properties": { "asset": { @@ -951,6 +971,12 @@ }, "balance": { "$ref": "#/definitions/Uint128" + }, + "config": { + "$ref": "#/definitions/AssetConfigRuntime" + }, + "shares": { + "$ref": "#/definitions/Uint128" } }, "additionalProperties": false @@ -1167,7 +1193,9 @@ "type": "object", "required": [ "asset", - "balance" + "balance", + "config", + "shares" ], "properties": { "asset": { @@ -1175,6 +1203,12 @@ }, "balance": { "$ref": "#/definitions/Uint128" + }, + "config": { + "$ref": "#/definitions/AssetConfigRuntime" + }, + "shares": { + "$ref": "#/definitions/Uint128" } }, "additionalProperties": false, @@ -1183,6 +1217,36 @@ "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", "type": "string" }, + "AssetConfigRuntime": { + "type": "object", + "required": [ + "harvested", + "last_taken_s", + "stake_config", + "taken", + "yearly_take_rate" + ], + "properties": { + "harvested": { + "$ref": "#/definitions/Uint128" + }, + "last_taken_s": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "stake_config": { + "$ref": "#/definitions/StakeConfig" + }, + "taken": { + "$ref": "#/definitions/Uint128" + }, + "yearly_take_rate": { + "$ref": "#/definitions/Decimal" + } + }, + "additionalProperties": false + }, "AssetInfoBase_for_Addr": { "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", "oneOf": [ @@ -1212,6 +1276,76 @@ } ] }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "StakeConfig": { + "oneOf": [ + { + "type": "string", + "enum": [ + "default" + ] + }, + { + "type": "object", + "required": [ + "astroport" + ], + "properties": { + "astroport": { + "type": "object", + "required": [ + "contract", + "reward_infos" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + }, + "reward_infos": { + "type": "array", + "items": { + "$ref": "#/definitions/AssetInfoBase_for_Addr" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ve3" + ], + "properties": { + "ve3": { + "type": "object", + "required": [ + "contract", + "reward_infos" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + }, + "reward_infos": { + "type": "array", + "items": { + "$ref": "#/definitions/AssetInfoBase_for_Addr" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, "Uint128": { "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", "type": "string" @@ -1230,6 +1364,36 @@ "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", "type": "string" }, + "AssetConfigRuntime": { + "type": "object", + "required": [ + "harvested", + "last_taken_s", + "stake_config", + "taken", + "yearly_take_rate" + ], + "properties": { + "harvested": { + "$ref": "#/definitions/Uint128" + }, + "last_taken_s": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "stake_config": { + "$ref": "#/definitions/StakeConfig" + }, + "taken": { + "$ref": "#/definitions/Uint128" + }, + "yearly_take_rate": { + "$ref": "#/definitions/Decimal" + } + }, + "additionalProperties": false + }, "AssetInfoBase_for_Addr": { "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", "oneOf": [ @@ -1259,11 +1423,83 @@ } ] }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "StakeConfig": { + "oneOf": [ + { + "type": "string", + "enum": [ + "default" + ] + }, + { + "type": "object", + "required": [ + "astroport" + ], + "properties": { + "astroport": { + "type": "object", + "required": [ + "contract", + "reward_infos" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + }, + "reward_infos": { + "type": "array", + "items": { + "$ref": "#/definitions/AssetInfoBase_for_Addr" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ve3" + ], + "properties": { + "ve3": { + "type": "object", + "required": [ + "contract", + "reward_infos" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + }, + "reward_infos": { + "type": "array", + "items": { + "$ref": "#/definitions/AssetInfoBase_for_Addr" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, "StakedBalanceRes": { "type": "object", "required": [ "asset", - "balance" + "balance", + "config", + "shares" ], "properties": { "asset": { @@ -1271,6 +1507,12 @@ }, "balance": { "$ref": "#/definitions/Uint128" + }, + "config": { + "$ref": "#/definitions/AssetConfigRuntime" + }, + "shares": { + "$ref": "#/definitions/Uint128" } }, "additionalProperties": false diff --git a/contracts/alliance-hub/schema/raw/execute.json b/contracts/alliance-hub/schema/raw/execute.json index bcf2472..74705b4 100644 --- a/contracts/alliance-hub/schema/raw/execute.json +++ b/contracts/alliance-hub/schema/raw/execute.json @@ -117,7 +117,7 @@ "additionalProperties": { "type": "array", "items": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" + "$ref": "#/definitions/AssetInfoWithConfig" } } } @@ -398,22 +398,6 @@ }, "additionalProperties": false }, - "AssetConfig": { - "type": "object", - "required": [ - "stake_config", - "yearly_take_rate" - ], - "properties": { - "stake_config": { - "$ref": "#/definitions/StakeConfig" - }, - "yearly_take_rate": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, "AssetDistribution": { "type": "object", "required": [ @@ -465,18 +449,18 @@ "info" ], "properties": { - "config": { + "info": { + "$ref": "#/definitions/AssetInfoBase_for_Addr" + }, + "yearly_take_rate": { "anyOf": [ { - "$ref": "#/definitions/AssetConfig" + "$ref": "#/definitions/Decimal" }, { "type": "null" } ] - }, - "info": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" } }, "additionalProperties": false @@ -510,72 +494,6 @@ "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", "type": "string" }, - "StakeConfig": { - "oneOf": [ - { - "type": "string", - "enum": [ - "default" - ] - }, - { - "type": "object", - "required": [ - "astroport" - ], - "properties": { - "astroport": { - "type": "object", - "required": [ - "contract", - "reward_infos" - ], - "properties": { - "contract": { - "$ref": "#/definitions/Addr" - }, - "reward_infos": { - "type": "array", - "items": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "ve3" - ], - "properties": { - "ve3": { - "type": "object", - "required": [ - "contract", - "reward_infos" - ], - "properties": { - "contract": { - "$ref": "#/definitions/Addr" - }, - "reward_infos": { - "type": "array", - "items": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, "Uint128": { "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", "type": "string" diff --git a/contracts/alliance-hub/schema/raw/response_to_all_staked_balances.json b/contracts/alliance-hub/schema/raw/response_to_all_staked_balances.json index fe51246..98ba84c 100644 --- a/contracts/alliance-hub/schema/raw/response_to_all_staked_balances.json +++ b/contracts/alliance-hub/schema/raw/response_to_all_staked_balances.json @@ -10,6 +10,36 @@ "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", "type": "string" }, + "AssetConfigRuntime": { + "type": "object", + "required": [ + "harvested", + "last_taken_s", + "stake_config", + "taken", + "yearly_take_rate" + ], + "properties": { + "harvested": { + "$ref": "#/definitions/Uint128" + }, + "last_taken_s": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "stake_config": { + "$ref": "#/definitions/StakeConfig" + }, + "taken": { + "$ref": "#/definitions/Uint128" + }, + "yearly_take_rate": { + "$ref": "#/definitions/Decimal" + } + }, + "additionalProperties": false + }, "AssetInfoBase_for_Addr": { "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", "oneOf": [ @@ -39,11 +69,83 @@ } ] }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "StakeConfig": { + "oneOf": [ + { + "type": "string", + "enum": [ + "default" + ] + }, + { + "type": "object", + "required": [ + "astroport" + ], + "properties": { + "astroport": { + "type": "object", + "required": [ + "contract", + "reward_infos" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + }, + "reward_infos": { + "type": "array", + "items": { + "$ref": "#/definitions/AssetInfoBase_for_Addr" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ve3" + ], + "properties": { + "ve3": { + "type": "object", + "required": [ + "contract", + "reward_infos" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + }, + "reward_infos": { + "type": "array", + "items": { + "$ref": "#/definitions/AssetInfoBase_for_Addr" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, "StakedBalanceRes": { "type": "object", "required": [ "asset", - "balance" + "balance", + "config", + "shares" ], "properties": { "asset": { @@ -51,6 +153,12 @@ }, "balance": { "$ref": "#/definitions/Uint128" + }, + "config": { + "$ref": "#/definitions/AssetConfigRuntime" + }, + "shares": { + "$ref": "#/definitions/Uint128" } }, "additionalProperties": false diff --git a/contracts/alliance-hub/schema/raw/response_to_staked_balance.json b/contracts/alliance-hub/schema/raw/response_to_staked_balance.json index 25f62b5..58f18f7 100644 --- a/contracts/alliance-hub/schema/raw/response_to_staked_balance.json +++ b/contracts/alliance-hub/schema/raw/response_to_staked_balance.json @@ -4,7 +4,9 @@ "type": "object", "required": [ "asset", - "balance" + "balance", + "config", + "shares" ], "properties": { "asset": { @@ -12,6 +14,12 @@ }, "balance": { "$ref": "#/definitions/Uint128" + }, + "config": { + "$ref": "#/definitions/AssetConfigRuntime" + }, + "shares": { + "$ref": "#/definitions/Uint128" } }, "additionalProperties": false, @@ -20,6 +28,36 @@ "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", "type": "string" }, + "AssetConfigRuntime": { + "type": "object", + "required": [ + "harvested", + "last_taken_s", + "stake_config", + "taken", + "yearly_take_rate" + ], + "properties": { + "harvested": { + "$ref": "#/definitions/Uint128" + }, + "last_taken_s": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "stake_config": { + "$ref": "#/definitions/StakeConfig" + }, + "taken": { + "$ref": "#/definitions/Uint128" + }, + "yearly_take_rate": { + "$ref": "#/definitions/Decimal" + } + }, + "additionalProperties": false + }, "AssetInfoBase_for_Addr": { "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", "oneOf": [ @@ -49,6 +87,76 @@ } ] }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "StakeConfig": { + "oneOf": [ + { + "type": "string", + "enum": [ + "default" + ] + }, + { + "type": "object", + "required": [ + "astroport" + ], + "properties": { + "astroport": { + "type": "object", + "required": [ + "contract", + "reward_infos" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + }, + "reward_infos": { + "type": "array", + "items": { + "$ref": "#/definitions/AssetInfoBase_for_Addr" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ve3" + ], + "properties": { + "ve3": { + "type": "object", + "required": [ + "contract", + "reward_infos" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + }, + "reward_infos": { + "type": "array", + "items": { + "$ref": "#/definitions/AssetInfoBase_for_Addr" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, "Uint128": { "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", "type": "string" diff --git a/contracts/alliance-hub/schema/raw/response_to_total_staked_balances.json b/contracts/alliance-hub/schema/raw/response_to_total_staked_balances.json index fe51246..98ba84c 100644 --- a/contracts/alliance-hub/schema/raw/response_to_total_staked_balances.json +++ b/contracts/alliance-hub/schema/raw/response_to_total_staked_balances.json @@ -10,6 +10,36 @@ "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", "type": "string" }, + "AssetConfigRuntime": { + "type": "object", + "required": [ + "harvested", + "last_taken_s", + "stake_config", + "taken", + "yearly_take_rate" + ], + "properties": { + "harvested": { + "$ref": "#/definitions/Uint128" + }, + "last_taken_s": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "stake_config": { + "$ref": "#/definitions/StakeConfig" + }, + "taken": { + "$ref": "#/definitions/Uint128" + }, + "yearly_take_rate": { + "$ref": "#/definitions/Decimal" + } + }, + "additionalProperties": false + }, "AssetInfoBase_for_Addr": { "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", "oneOf": [ @@ -39,11 +69,83 @@ } ] }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "StakeConfig": { + "oneOf": [ + { + "type": "string", + "enum": [ + "default" + ] + }, + { + "type": "object", + "required": [ + "astroport" + ], + "properties": { + "astroport": { + "type": "object", + "required": [ + "contract", + "reward_infos" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + }, + "reward_infos": { + "type": "array", + "items": { + "$ref": "#/definitions/AssetInfoBase_for_Addr" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ve3" + ], + "properties": { + "ve3": { + "type": "object", + "required": [ + "contract", + "reward_infos" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + }, + "reward_infos": { + "type": "array", + "items": { + "$ref": "#/definitions/AssetInfoBase_for_Addr" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, "StakedBalanceRes": { "type": "object", "required": [ "asset", - "balance" + "balance", + "config", + "shares" ], "properties": { "asset": { @@ -51,6 +153,12 @@ }, "balance": { "$ref": "#/definitions/Uint128" + }, + "config": { + "$ref": "#/definitions/AssetConfigRuntime" + }, + "shares": { + "$ref": "#/definitions/Uint128" } }, "additionalProperties": false diff --git a/contracts/alliance-hub/src/contract.rs b/contracts/alliance-hub/src/contract.rs index 65866dc..0802896 100644 --- a/contracts/alliance-hub/src/contract.rs +++ b/contracts/alliance-hub/src/contract.rs @@ -31,6 +31,7 @@ use alliance_protocol::alliance_protocol::{ // use alliance_protocol::alliance_oracle_types::{AssetStaked, ChainId, EmissionsDistribution}; use crate::error::ContractError; +use crate::migrations::migrate_state; use crate::state::{ ASSET_CONFIG, ASSET_REWARD_DISTRIBUTION, ASSET_REWARD_RATE, BALANCES, CONFIG, TEMP_BALANCE, TOTAL_BALANCES_SHARES, UNCLAIMED_REWARDS, USER_ASSET_REWARD_RATE, VALIDATORS, WHITELIST, @@ -53,6 +54,8 @@ pub fn migrate(mut deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result Result<(), ContractError> { +pub(crate) fn migrate_state(deps: DepsMut) -> Result<(), ContractError> { const OLD_TOTAL_BALANCES: Map<&AssetInfo, Uint128> = Map::new("total_balances"); let old_map = OLD_TOTAL_BALANCES diff --git a/contracts/alliance-hub/src/tests/assets.rs b/contracts/alliance-hub/src/tests/assets.rs index 37543ad..4cd717b 100644 --- a/contracts/alliance-hub/src/tests/assets.rs +++ b/contracts/alliance-hub/src/tests/assets.rs @@ -1,13 +1,18 @@ +use std::collections::HashMap; + +use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; +use cosmwasm_std::{from_json, Decimal, Response}; +use cw_asset::AssetInfo; + +use alliance_protocol::alliance_protocol::{ + AssetInfoWithConfig, ExecuteMsg, QueryMsg, WhitelistedAssetsResponse, +}; + use crate::contract::execute; use crate::error::ContractError; use crate::query::query; use crate::state::WHITELIST; use crate::tests::helpers::{remove_assets, setup_contract, whitelist_assets}; -use alliance_protocol::alliance_protocol::{ExecuteMsg, QueryMsg, WhitelistedAssetsResponse}; -use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; -use cosmwasm_std::{from_json, Response}; -use cw_asset::AssetInfo; -use std::collections::HashMap; #[test] fn test_whitelist_assets() { @@ -17,7 +22,10 @@ fn test_whitelist_assets() { deps.as_mut(), HashMap::from([( "chain-1".to_string(), - vec![AssetInfo::Native("asset1".to_string())], + vec![AssetInfoWithConfig { + info: AssetInfo::Native("asset1".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }], )]), ); assert_eq!( @@ -25,7 +33,7 @@ fn test_whitelist_assets() { Response::default().add_attributes(vec![ ("action", "whitelist_assets"), ("chain_id", "chain-1"), - ("assets", "native:asset1") + ("assets", "native:asset1"), ]) ); @@ -34,8 +42,14 @@ fn test_whitelist_assets() { HashMap::from([( "chain-1".to_string(), vec![ - AssetInfo::Native("asset2".to_string()), - AssetInfo::Native("asset3".to_string()), + AssetInfoWithConfig { + info: AssetInfo::Native("asset2".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }, + AssetInfoWithConfig { + info: AssetInfo::Native("asset3".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }, ], )]), ); @@ -44,7 +58,7 @@ fn test_whitelist_assets() { Response::default().add_attributes(vec![ ("action", "whitelist_assets"), ("chain_id", "chain-1"), - ("assets", "native:asset2,native:asset3") + ("assets", "native:asset2,native:asset3"), ]) ); @@ -66,7 +80,7 @@ fn test_whitelist_assets() { vec![ AssetInfo::Native("asset1".to_string()), AssetInfo::Native("asset2".to_string()), - AssetInfo::Native("asset3".to_string()) + AssetInfo::Native("asset3".to_string()), ] )]) ) @@ -82,7 +96,10 @@ fn test_whitelist_asset_unauthorized() { mock_info("admin", &[]), ExecuteMsg::WhitelistAssets(HashMap::from([( "chain-1".to_string(), - vec![AssetInfo::Native("asset1".to_string())], + vec![AssetInfoWithConfig { + info: AssetInfo::Native("asset1".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }], )])), ) .unwrap_err(); @@ -98,8 +115,14 @@ fn test_remove_assets() { HashMap::from([( "chain-1".to_string(), vec![ - AssetInfo::Native("asset1".to_string()), - AssetInfo::Native("asset2".to_string()), + AssetInfoWithConfig { + info: AssetInfo::Native("asset1".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }, + AssetInfoWithConfig { + info: AssetInfo::Native("asset2".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }, ], )]), ); @@ -109,7 +132,7 @@ fn test_remove_assets() { response, Response::default().add_attributes(vec![ ("action", "remove_assets"), - ("assets", "native:asset1") + ("assets", "native:asset1"), ]) ); diff --git a/contracts/alliance-hub/src/tests/helpers.rs b/contracts/alliance-hub/src/tests/helpers.rs index e85a4ad..e4ec07a 100644 --- a/contracts/alliance-hub/src/tests/helpers.rs +++ b/contracts/alliance-hub/src/tests/helpers.rs @@ -9,8 +9,9 @@ use cw_asset::{Asset, AssetInfo}; use alliance_protocol::alliance_protocol::{ AllPendingRewardsQuery, AllianceDelegateMsg, AllianceDelegation, AllianceRedelegateMsg, - AllianceRedelegation, AllianceUndelegateMsg, AssetDistribution, AssetQuery, ChainId, Config, - Cw20HookMsg, ExecuteMsg, InstantiateMsg, PendingRewardsRes, QueryMsg, StakedBalanceRes, + AllianceRedelegation, AllianceUndelegateMsg, AssetDistribution, AssetInfoWithConfig, + AssetQuery, ChainId, Config, Cw20HookMsg, ExecuteMsg, InstantiateMsg, PendingRewardsRes, + QueryMsg, StakedBalanceRes, }; use crate::contract::{execute, instantiate}; @@ -49,7 +50,10 @@ pub fn set_alliance_asset(deps: DepsMut) { .unwrap(); } -pub fn whitelist_assets(deps: DepsMut, assets: HashMap>) -> Response { +pub fn whitelist_assets( + deps: DepsMut, + assets: HashMap>, +) -> Response { let info = mock_info("gov", &[]); let env = mock_env(); diff --git a/contracts/alliance-hub/src/tests/rewards.rs b/contracts/alliance-hub/src/tests/rewards.rs index cb35395..2051ec0 100644 --- a/contracts/alliance-hub/src/tests/rewards.rs +++ b/contracts/alliance-hub/src/tests/rewards.rs @@ -9,7 +9,9 @@ use cw_asset::AssetInfo; use terra_proto_rs::alliance::alliance::MsgClaimDelegationRewards; use terra_proto_rs::traits::Message; -use alliance_protocol::alliance_protocol::{AssetDistribution, ExecuteMsg, PendingRewardsRes}; +use alliance_protocol::alliance_protocol::{ + AssetDistribution, AssetInfoWithConfig, ExecuteMsg, PendingRewardsRes, +}; use crate::contract::execute; use crate::error::ContractError; @@ -192,7 +194,10 @@ fn claim_user_rewards() { deps.as_mut(), HashMap::from([( "chain-1".to_string(), - vec![AssetInfo::Native("aWHALE".to_string())], + vec![AssetInfoWithConfig { + info: AssetInfo::Native("aWHALE".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }], )]), ); stake(deps.as_mut(), "user1", 1000000, "aWHALE"); @@ -347,7 +352,10 @@ fn claim_user_rewards_after_staking() { deps.as_mut(), HashMap::from([( "chain-1".to_string(), - vec![AssetInfo::Native("aWHALE".to_string())], + vec![AssetInfoWithConfig { + info: AssetInfo::Native("aWHALE".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }], )]), ); stake(deps.as_mut(), "user1", 1000000, "aWHALE"); @@ -420,8 +428,14 @@ fn claim_rewards_after_staking_and_unstaking() { HashMap::from([( "chain-1".to_string(), vec![ - AssetInfo::Native("aWHALE".to_string()), - AssetInfo::Native("bWHALE".to_string()), + AssetInfoWithConfig { + info: AssetInfo::Native("aWHALE".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }, + AssetInfoWithConfig { + info: AssetInfo::Native("bWHALE".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }, ], )]), ); @@ -511,8 +525,14 @@ fn claim_rewards_after_rebalancing_emissions() { HashMap::from([( "chain-1".to_string(), vec![ - AssetInfo::Native("aWHALE".to_string()), - AssetInfo::Native("bWHALE".to_string()), + AssetInfoWithConfig { + info: AssetInfo::Native("aWHALE".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }, + AssetInfoWithConfig { + info: AssetInfo::Native("bWHALE".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }, ], )]), ); diff --git a/contracts/alliance-hub/src/tests/stake_unstake.rs b/contracts/alliance-hub/src/tests/stake_unstake.rs index dfdcc4e..b777db9 100644 --- a/contracts/alliance-hub/src/tests/stake_unstake.rs +++ b/contracts/alliance-hub/src/tests/stake_unstake.rs @@ -5,11 +5,14 @@ use crate::tests::helpers::{ query_all_staked_balances, setup_contract, stake, stake_cw20, unstake, unstake_cw20, whitelist_assets, }; -use alliance_protocol::alliance_protocol::{ExecuteMsg, StakedBalanceRes}; +use alliance_protocol::alliance_protocol::{AssetInfoWithConfig, ExecuteMsg, StakedBalanceRes}; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; -use cosmwasm_std::{coin, to_json_binary, Addr, BankMsg, CosmosMsg, Response, Uint128, WasmMsg}; +use cosmwasm_std::{ + coin, to_json_binary, Addr, BankMsg, CosmosMsg, Decimal, Response, Uint128, WasmMsg, +}; use cw_asset::{Asset, AssetInfo}; use std::collections::HashMap; +use ve3_shared::msgs_asset_staking::AssetConfigRuntime; mod cw20_support { use super::*; @@ -22,7 +25,10 @@ mod cw20_support { deps.as_mut(), HashMap::from([( "chain-1".to_string(), - vec![AssetInfo::Cw20(Addr::unchecked("asset1"))], + vec![AssetInfoWithConfig { + info: AssetInfo::Cw20(Addr::unchecked("asset1")), + yearly_take_rate: Some(Decimal::percent(5)), + }], )]), ); @@ -82,13 +88,20 @@ mod cw20_support { assert_eq!(total_shares, Uint128::new(200)); let total_balances_res = query_all_staked_balances(deps.as_ref()); + assert_eq!( total_balances_res, vec![StakedBalanceRes { asset: AssetInfo::Cw20(Addr::unchecked("asset1")), balance: Uint128::new(200), - shares: Default::default(), - config: Default::default(), + shares: Uint128::new(200), + config: AssetConfigRuntime { + last_taken_s: 1571797419u64, + taken: Default::default(), + harvested: Default::default(), + yearly_take_rate: Decimal::percent(5), + stake_config: Default::default(), + }, }] ); } @@ -101,7 +114,10 @@ mod cw20_support { deps.as_mut(), HashMap::from([( "chain-1".to_string(), - vec![AssetInfo::Cw20(Addr::unchecked("asset1"))], + vec![AssetInfoWithConfig { + info: AssetInfo::Cw20(Addr::unchecked("asset1")), + yearly_take_rate: Some(Decimal::percent(5)), + }], )]), ); @@ -199,7 +215,10 @@ fn test_stake() { deps.as_mut(), HashMap::from([( "chain-1".to_string(), - vec![AssetInfo::Native("asset1".to_string())], + vec![AssetInfoWithConfig { + info: AssetInfo::Native("asset1".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }], )]), ); @@ -264,8 +283,14 @@ fn test_stake() { vec![StakedBalanceRes { asset: AssetInfo::Native("asset1".to_string()), balance: Uint128::new(200), - shares: Default::default(), - config: Default::default(), + shares: Uint128::new(200), + config: AssetConfigRuntime { + last_taken_s: 1571797419u64, + taken: Default::default(), + harvested: Default::default(), + yearly_take_rate: Decimal::percent(5), + stake_config: Default::default(), + }, }] ); } @@ -278,7 +303,10 @@ fn test_stake_invalid() { deps.as_mut(), HashMap::from([( "chain-1".to_string(), - vec![AssetInfo::Native("asset1".to_string())], + vec![AssetInfoWithConfig { + info: AssetInfo::Native("asset1".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }], )]), ); // Stake an unwhitelisted asset @@ -315,7 +343,10 @@ fn test_unstake() { deps.as_mut(), HashMap::from([( "chain-1".to_string(), - vec![AssetInfo::Native("asset1".to_string())], + vec![AssetInfoWithConfig { + info: AssetInfo::Native("asset1".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }], )]), ); stake(deps.as_mut(), "user1", 150, "asset1"); @@ -375,7 +406,7 @@ fn test_unstake() { assert_eq!(balance, Uint128::new(50)); // User unstakes more than they have, this will return everything the user has but no more - let res = unstake(deps.as_mut(), "user1", 100, "asset1"); + unstake(deps.as_mut(), "user1", 100, "asset1"); let (total_balance, total_shares) = TOTAL_BALANCES_SHARES .load( @@ -396,7 +427,10 @@ fn test_unstake_invalid() { deps.as_mut(), HashMap::from([( "chain-1".to_string(), - vec![AssetInfo::Native("asset1".to_string())], + vec![AssetInfoWithConfig { + info: AssetInfo::Native("asset1".to_string()), + yearly_take_rate: Some(Decimal::percent(5)), + }], )]), ); stake(deps.as_mut(), "user1", 100, "asset1");