diff --git a/contracts/liquidity_hub/bonding-manager/schema/bonding-manager.json b/contracts/liquidity_hub/bonding-manager/schema/bonding-manager.json index e377acb2..ee01742b 100644 --- a/contracts/liquidity_hub/bonding-manager/schema/bonding-manager.json +++ b/contracts/liquidity_hub/bonding-manager/schema/bonding-manager.json @@ -31,12 +31,10 @@ "type": "string" }, "grace_period": { - "description": "Grace period the maximum age of a bucket before fees are forwarded from it", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] + "description": "Grace period the maximum age of a epoch bucket before it's considered expired and fees are forwarded from it", + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "growth_rate": { "description": "Weight grow rate. Needs to be between 0 and 1.", @@ -47,12 +45,10 @@ ] }, "unbonding_period": { - "description": "Unbonding period in nanoseconds. The time that needs to pass before an unbonded position can be withdrawn", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] + "description": "Unbonding period in epochs. The time (in epochs) that needs to pass before an unbonded position can be withdrawn", + "type": "integer", + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false, @@ -60,10 +56,6 @@ "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" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 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 `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } }, @@ -165,14 +157,12 @@ }, "unbonding_period": { "description": "The unbonding period.", - "anyOf": [ - { - "$ref": "#/definitions/Uint64" - }, - { - "type": "null" - } - ] + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false @@ -514,6 +504,15 @@ "description": "The address to check for weight.", "type": "string" }, + "epoch_id": { + "description": "The timestamp to check for weight. If none is provided, the current block time is used.", + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + }, "global_index": { "description": "The global index to check for weight. If none is provided, the current global index is used.", "anyOf": [ @@ -524,17 +523,6 @@ "type": "null" } ] - }, - "timestamp": { - "description": "The timestamp to check for weight. If none is provided, the current block time is used.", - "anyOf": [ - { - "$ref": "#/definitions/Timestamp" - }, - { - "type": "null" - } - ] } }, "additionalProperties": false @@ -608,7 +596,7 @@ "required": [ "bonded_amount", "bonded_assets", - "timestamp", + "last_updated", "weight" ], "properties": { @@ -627,13 +615,11 @@ "$ref": "#/definitions/Coin" } }, - "timestamp": { - "description": "The timestamp at which the total bond was registered.", - "allOf": [ - { - "$ref": "#/definitions/Timestamp" - } - ] + "last_updated": { + "description": "The epoch id at which the total bond was updated.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "weight": { "description": "The total weight of the bond at the given block height.", @@ -646,21 +632,9 @@ }, "additionalProperties": false }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, "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" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 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 `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } }, @@ -691,14 +665,12 @@ }, "first_bonded_epoch_id": { "description": "If Some, the epoch id at which the user/address bonded first time. None is used when this Response is used to check the bonded assets in the contract.", - "anyOf": [ - { - "$ref": "#/definitions/Uint64" - }, - { - "type": "null" - } - ] + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 }, "total_bonded": { "description": "The total amount of bonded tokens by the address. Bear in mind the bonded assets are considered to be equal for this purpose.", @@ -729,10 +701,6 @@ "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" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 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 `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } }, @@ -796,7 +764,9 @@ "$ref": "#/definitions/GlobalIndex" }, "id": { - "$ref": "#/definitions/Uint64" + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "start_time": { "$ref": "#/definitions/Timestamp" @@ -815,7 +785,7 @@ "required": [ "bonded_amount", "bonded_assets", - "timestamp", + "last_updated", "weight" ], "properties": { @@ -834,13 +804,11 @@ "$ref": "#/definitions/Coin" } }, - "timestamp": { - "description": "The timestamp at which the total bond was registered.", - "allOf": [ - { - "$ref": "#/definitions/Timestamp" - } - ] + "last_updated": { + "description": "The epoch id at which the total bond was updated.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "weight": { "description": "The total weight of the bond at the given block height.", @@ -905,12 +873,10 @@ ] }, "grace_period": { - "description": "The duration of the grace period in epochs, i.e. how many expired epochs can be claimed", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] + "description": "Grace period the maximum age of a epoch bucket before it's considered expired and fees are forwarded from it", + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "growth_rate": { "description": "A fraction that controls the effect of time on the weight of a bond. If the growth rate is set to zero, time will have no impact on the weight.", @@ -930,11 +896,9 @@ }, "unbonding_period": { "description": "Unbonding period in nanoseconds. The time that needs to pass before an unbonded position can be withdrawn", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] + "type": "integer", + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false, @@ -946,10 +910,6 @@ "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" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 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 `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } }, @@ -960,7 +920,7 @@ "required": [ "bonded_amount", "bonded_assets", - "timestamp", + "last_updated", "weight" ], "properties": { @@ -979,13 +939,11 @@ "$ref": "#/definitions/Coin" } }, - "timestamp": { - "description": "The timestamp at which the total bond was registered.", - "allOf": [ - { - "$ref": "#/definitions/Timestamp" - } - ] + "last_updated": { + "description": "The epoch id at which the total bond was updated.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "weight": { "description": "The total weight of the bond at the given block height.", @@ -1013,21 +971,9 @@ } } }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, "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" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 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 `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } }, @@ -1159,7 +1105,7 @@ "required": [ "asset", "created_at_epoch", - "timestamp", + "updated_last", "weight" ], "properties": { @@ -1173,19 +1119,15 @@ }, "created_at_epoch": { "description": "The epoch id at which the Bond was created.", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, - "timestamp": { - "description": "The timestamp at which the bond was done.", - "allOf": [ - { - "$ref": "#/definitions/Timestamp" - } - ] + "updated_last": { + "description": "The epoch id at which the bond was last time updated.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "weight": { "description": "The weight of the bond at the given block height.", @@ -1213,21 +1155,9 @@ } } }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, "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" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 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 `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } }, @@ -1238,9 +1168,9 @@ "type": "object", "required": [ "address", + "epoch_id", "global_weight", "share", - "timestamp", "weight" ], "properties": { @@ -1248,6 +1178,12 @@ "description": "The weight of the address.", "type": "string" }, + "epoch_id": { + "description": "The epoch id at which the weight was calculated.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, "global_weight": { "description": "The global weight of the contract.", "allOf": [ @@ -1264,14 +1200,6 @@ } ] }, - "timestamp": { - "description": "The timestamp at which the weight was calculated.", - "allOf": [ - { - "$ref": "#/definitions/Timestamp" - } - ] - }, "weight": { "description": "The weight of the address at the given timestamp.", "allOf": [ @@ -1287,21 +1215,9 @@ "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" }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, "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" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 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 `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } }, diff --git a/contracts/liquidity_hub/bonding-manager/schema/raw/execute.json b/contracts/liquidity_hub/bonding-manager/schema/raw/execute.json index 9fceba5b..c6a562de 100644 --- a/contracts/liquidity_hub/bonding-manager/schema/raw/execute.json +++ b/contracts/liquidity_hub/bonding-manager/schema/raw/execute.json @@ -96,14 +96,12 @@ }, "unbonding_period": { "description": "The unbonding period.", - "anyOf": [ - { - "$ref": "#/definitions/Uint64" - }, - { - "type": "null" - } - ] + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false diff --git a/contracts/liquidity_hub/bonding-manager/schema/raw/instantiate.json b/contracts/liquidity_hub/bonding-manager/schema/raw/instantiate.json index b0d74ffa..f93d08e6 100644 --- a/contracts/liquidity_hub/bonding-manager/schema/raw/instantiate.json +++ b/contracts/liquidity_hub/bonding-manager/schema/raw/instantiate.json @@ -27,12 +27,10 @@ "type": "string" }, "grace_period": { - "description": "Grace period the maximum age of a bucket before fees are forwarded from it", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] + "description": "Grace period the maximum age of a epoch bucket before it's considered expired and fees are forwarded from it", + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "growth_rate": { "description": "Weight grow rate. Needs to be between 0 and 1.", @@ -43,12 +41,10 @@ ] }, "unbonding_period": { - "description": "Unbonding period in nanoseconds. The time that needs to pass before an unbonded position can be withdrawn", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] + "description": "Unbonding period in epochs. The time (in epochs) that needs to pass before an unbonded position can be withdrawn", + "type": "integer", + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false, @@ -56,10 +52,6 @@ "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" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 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 `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } } diff --git a/contracts/liquidity_hub/bonding-manager/schema/raw/query.json b/contracts/liquidity_hub/bonding-manager/schema/raw/query.json index 096226bb..3c5ab6ae 100644 --- a/contracts/liquidity_hub/bonding-manager/schema/raw/query.json +++ b/contracts/liquidity_hub/bonding-manager/schema/raw/query.json @@ -123,6 +123,15 @@ "description": "The address to check for weight.", "type": "string" }, + "epoch_id": { + "description": "The timestamp to check for weight. If none is provided, the current block time is used.", + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + }, "global_index": { "description": "The global index to check for weight. If none is provided, the current global index is used.", "anyOf": [ @@ -133,17 +142,6 @@ "type": "null" } ] - }, - "timestamp": { - "description": "The timestamp to check for weight. If none is provided, the current block time is used.", - "anyOf": [ - { - "$ref": "#/definitions/Timestamp" - }, - { - "type": "null" - } - ] } }, "additionalProperties": false @@ -217,7 +215,7 @@ "required": [ "bonded_amount", "bonded_assets", - "timestamp", + "last_updated", "weight" ], "properties": { @@ -236,13 +234,11 @@ "$ref": "#/definitions/Coin" } }, - "timestamp": { - "description": "The timestamp at which the total bond was registered.", - "allOf": [ - { - "$ref": "#/definitions/Timestamp" - } - ] + "last_updated": { + "description": "The epoch id at which the total bond was updated.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "weight": { "description": "The total weight of the bond at the given block height.", @@ -255,21 +251,9 @@ }, "additionalProperties": false }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, "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" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 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 `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } } diff --git a/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_bonded.json b/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_bonded.json index d8a0ddbd..6deb74cb 100644 --- a/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_bonded.json +++ b/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_bonded.json @@ -17,14 +17,12 @@ }, "first_bonded_epoch_id": { "description": "If Some, the epoch id at which the user/address bonded first time. None is used when this Response is used to check the bonded assets in the contract.", - "anyOf": [ - { - "$ref": "#/definitions/Uint64" - }, - { - "type": "null" - } - ] + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 }, "total_bonded": { "description": "The total amount of bonded tokens by the address. Bear in mind the bonded assets are considered to be equal for this purpose.", @@ -55,10 +53,6 @@ "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" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 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 `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } } diff --git a/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_claimable.json b/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_claimable.json index 6a728ff2..41023177 100644 --- a/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_claimable.json +++ b/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_claimable.json @@ -58,7 +58,9 @@ "$ref": "#/definitions/GlobalIndex" }, "id": { - "$ref": "#/definitions/Uint64" + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "start_time": { "$ref": "#/definitions/Timestamp" @@ -77,7 +79,7 @@ "required": [ "bonded_amount", "bonded_assets", - "timestamp", + "last_updated", "weight" ], "properties": { @@ -96,13 +98,11 @@ "$ref": "#/definitions/Coin" } }, - "timestamp": { - "description": "The timestamp at which the total bond was registered.", - "allOf": [ - { - "$ref": "#/definitions/Timestamp" - } - ] + "last_updated": { + "description": "The epoch id at which the total bond was updated.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "weight": { "description": "The total weight of the bond at the given block height.", diff --git a/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_config.json b/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_config.json index 3d6850fc..20a56f53 100644 --- a/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_config.json +++ b/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_config.json @@ -32,12 +32,10 @@ ] }, "grace_period": { - "description": "The duration of the grace period in epochs, i.e. how many expired epochs can be claimed", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] + "description": "Grace period the maximum age of a epoch bucket before it's considered expired and fees are forwarded from it", + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "growth_rate": { "description": "A fraction that controls the effect of time on the weight of a bond. If the growth rate is set to zero, time will have no impact on the weight.", @@ -57,11 +55,9 @@ }, "unbonding_period": { "description": "Unbonding period in nanoseconds. The time that needs to pass before an unbonded position can be withdrawn", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] + "type": "integer", + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false, @@ -73,10 +69,6 @@ "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" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 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 `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } } diff --git a/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_global_index.json b/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_global_index.json index 9b88c08c..4128e977 100644 --- a/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_global_index.json +++ b/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_global_index.json @@ -5,7 +5,7 @@ "required": [ "bonded_amount", "bonded_assets", - "timestamp", + "last_updated", "weight" ], "properties": { @@ -24,13 +24,11 @@ "$ref": "#/definitions/Coin" } }, - "timestamp": { - "description": "The timestamp at which the total bond was registered.", - "allOf": [ - { - "$ref": "#/definitions/Timestamp" - } - ] + "last_updated": { + "description": "The epoch id at which the total bond was updated.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "weight": { "description": "The total weight of the bond at the given block height.", @@ -58,21 +56,9 @@ } } }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, "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" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 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 `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } } diff --git a/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_unbonding.json b/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_unbonding.json index 1582163d..ffa51158 100644 --- a/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_unbonding.json +++ b/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_unbonding.json @@ -31,7 +31,7 @@ "required": [ "asset", "created_at_epoch", - "timestamp", + "updated_last", "weight" ], "properties": { @@ -45,19 +45,15 @@ }, "created_at_epoch": { "description": "The epoch id at which the Bond was created.", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, - "timestamp": { - "description": "The timestamp at which the bond was done.", - "allOf": [ - { - "$ref": "#/definitions/Timestamp" - } - ] + "updated_last": { + "description": "The epoch id at which the bond was last time updated.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "weight": { "description": "The weight of the bond at the given block height.", @@ -85,21 +81,9 @@ } } }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, "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" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 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 `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } } diff --git a/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_weight.json b/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_weight.json index 0e017e02..bbe32476 100644 --- a/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_weight.json +++ b/contracts/liquidity_hub/bonding-manager/schema/raw/response_to_weight.json @@ -5,9 +5,9 @@ "type": "object", "required": [ "address", + "epoch_id", "global_weight", "share", - "timestamp", "weight" ], "properties": { @@ -15,6 +15,12 @@ "description": "The weight of the address.", "type": "string" }, + "epoch_id": { + "description": "The epoch id at which the weight was calculated.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, "global_weight": { "description": "The global weight of the contract.", "allOf": [ @@ -31,14 +37,6 @@ } ] }, - "timestamp": { - "description": "The timestamp at which the weight was calculated.", - "allOf": [ - { - "$ref": "#/definitions/Timestamp" - } - ] - }, "weight": { "description": "The weight of the address at the given timestamp.", "allOf": [ @@ -54,21 +52,9 @@ "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" }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, "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" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 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 `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } } diff --git a/contracts/liquidity_hub/bonding-manager/src/commands.rs b/contracts/liquidity_hub/bonding-manager/src/commands.rs index 5f74cb86..63441446 100644 --- a/contracts/liquidity_hub/bonding-manager/src/commands.rs +++ b/contracts/liquidity_hub/bonding-manager/src/commands.rs @@ -1,6 +1,6 @@ use cosmwasm_std::{ ensure, Addr, BankMsg, Coin, CosmosMsg, Decimal, DepsMut, Env, MessageInfo, Order, Response, - StdError, StdResult, SubMsg, Timestamp, Uint128, Uint64, + StdError, StdResult, SubMsg, Uint128, Uint64, }; use white_whale_std::bonding_manager::{Bond, Epoch, GlobalIndex}; @@ -17,7 +17,6 @@ use crate::{helpers, ContractError}; /// Bonds the provided asset. pub(crate) fn bond( mut deps: DepsMut, - timestamp: Timestamp, info: MessageInfo, env: Env, asset: Coin, @@ -43,14 +42,14 @@ pub(crate) fn bond( amount: Uint128::zero(), ..asset.clone() }, - created_at_epoch: Uint64::new(current_epoch.epoch.id), + created_at_epoch: current_epoch.epoch.id, ..Bond::default() }); // update local values bond.asset.amount = bond.asset.amount.checked_add(asset.amount)?; bond.weight = bond.weight.checked_add(asset.amount)?; - bond = update_local_weight(&mut deps, info.sender.clone(), timestamp, bond)?; + bond = update_local_weight(&mut deps, info.sender.clone(), current_epoch.epoch.id, bond)?; BOND.save(deps.storage, (&info.sender, &asset.denom), &bond)?; // update global values @@ -60,7 +59,7 @@ pub(crate) fn bond( global_index.bonded_amount = global_index.bonded_amount.checked_add(asset.amount)?; global_index.bonded_assets = asset::aggregate_coins(global_index.bonded_assets, vec![asset.clone()])?; - global_index = update_global_weight(&mut deps, timestamp, global_index)?; + global_index = update_global_weight(&mut deps, current_epoch.epoch.id, global_index)?; GLOBAL.save(deps.storage, &global_index)?; @@ -74,7 +73,6 @@ pub(crate) fn bond( /// Unbonds the provided amount of tokens pub(crate) fn unbond( mut deps: DepsMut, - timestamp: Timestamp, info: MessageInfo, env: Env, asset: Coin, @@ -96,8 +94,20 @@ pub(crate) fn unbond( ContractError::InsufficientBond ); + let config = CONFIG.load(deps.storage)?; + let current_epoch: white_whale_std::epoch_manager::epoch_manager::EpochResponse = + deps.querier.query_wasm_smart( + config.epoch_manager_addr, + &white_whale_std::epoch_manager::epoch_manager::QueryMsg::CurrentEpoch {}, + )?; + // update local values, decrease the bond - unbond = update_local_weight(&mut deps, info.sender.clone(), timestamp, unbond.clone())?; + unbond = update_local_weight( + &mut deps, + info.sender.clone(), + current_epoch.epoch.id, + unbond.clone(), + )?; let weight_slash = unbond.weight * Decimal::from_ratio(asset.amount, unbond.asset.amount); unbond.weight = unbond.weight.saturating_sub(weight_slash); unbond.asset.amount = unbond.asset.amount.saturating_sub(asset.amount); @@ -108,27 +118,20 @@ pub(crate) fn unbond( BOND.save(deps.storage, (&info.sender, &asset.denom), &unbond)?; } - let config = CONFIG.load(deps.storage)?; - let current_epoch: white_whale_std::epoch_manager::epoch_manager::EpochResponse = - deps.querier.query_wasm_smart( - config.epoch_manager_addr, - &white_whale_std::epoch_manager::epoch_manager::QueryMsg::CurrentEpoch {}, - )?; - // record the unbonding UNBOND.save( deps.storage, - (&info.sender, &asset.denom, timestamp.nanos()), + (&info.sender, &asset.denom, env.block.time.nanos()), &Bond { asset: asset.clone(), weight: Uint128::zero(), - timestamp, - created_at_epoch: Uint64::new(current_epoch.epoch.id), + updated_last: current_epoch.epoch.id, + created_at_epoch: current_epoch.epoch.id, }, )?; // update global values let mut global_index = GLOBAL.may_load(deps.storage)?.unwrap_or_default(); - global_index = update_global_weight(&mut deps, timestamp, global_index)?; + global_index = update_global_weight(&mut deps, current_epoch.epoch.id, global_index)?; global_index.bonded_amount = global_index.bonded_amount.saturating_sub(asset.amount); global_index.bonded_assets = white_whale_std::coin::deduct_coins(global_index.bonded_assets, vec![asset.clone()])?; @@ -149,25 +152,28 @@ pub(crate) fn unbond( /// Withdraws the rewards for the provided address pub(crate) fn withdraw( deps: DepsMut, - timestamp: Timestamp, address: Addr, denom: String, ) -> Result { - let config = CONFIG.load(deps.storage)?; - let unbondings: Vec<(u64, Bond)> = UNBOND .prefix((&address, &denom)) .range(deps.storage, None, None, Order::Ascending) .take(MAX_PAGE_LIMIT as usize) .collect::>>()?; - let mut refund_amount = Uint128::zero(); - ensure!(!unbondings.is_empty(), ContractError::NothingToWithdraw); + let config = CONFIG.load(deps.storage)?; + let current_epoch: white_whale_std::epoch_manager::epoch_manager::EpochResponse = + deps.querier.query_wasm_smart( + config.epoch_manager_addr, + &white_whale_std::epoch_manager::epoch_manager::QueryMsg::CurrentEpoch {}, + )?; + + let mut refund_amount = Uint128::zero(); for unbonding in unbondings { let (ts, bond) = unbonding; - if timestamp.minus_nanos(config.unbonding_period.u64()) >= bond.timestamp { + if current_epoch.epoch.id.saturating_sub(bond.created_at_epoch) >= config.unbonding_period { let denom = bond.asset.denom; refund_amount = refund_amount.checked_add(bond.asset.amount)?; @@ -199,7 +205,7 @@ pub(crate) fn update_config( info: MessageInfo, epoch_manager_addr: Option, pool_manager_addr: Option, - unbonding_period: Option, + unbonding_period: Option, growth_rate: Option, ) -> Result { // check the owner is the one who sent the message @@ -249,7 +255,7 @@ pub fn claim(deps: DepsMut, info: MessageInfo) -> Result Result { @@ -449,7 +454,7 @@ pub(crate) fn on_epoch_created( // This happens only on the very first epoch where Global has not been initialised yet if global.is_none() { let initial_global_index = GlobalIndex { - timestamp: env.block.time, + last_updated: current_epoch.id, ..Default::default() }; GLOBAL.save(deps.storage, &initial_global_index)?; @@ -457,7 +462,7 @@ pub(crate) fn on_epoch_created( deps.storage, ¤t_epoch.id.to_be_bytes(), &Epoch { - id: current_epoch.id.into(), + id: current_epoch.id, start_time: current_epoch.start_time, global_index: initial_global_index, ..Epoch::default() @@ -523,10 +528,12 @@ pub(crate) fn on_epoch_created( // Create a new bucket for the rewards flowing from this time on, i.e. to be distributed in // the next epoch. Also, forwards the expiring epoch (only 21 epochs are live at a given moment) - let next_epoch_id = Uint64::new(current_epoch.id).checked_add(Uint64::one())?; + let next_epoch_id = Uint64::new(current_epoch.id) + .checked_add(Uint64::one())? + .u64(); EPOCHS.save( deps.storage, - &next_epoch_id.u64().to_be_bytes(), + &next_epoch_id.to_be_bytes(), &Epoch { id: next_epoch_id, start_time: current_epoch.start_time.plus_days(1), diff --git a/contracts/liquidity_hub/bonding-manager/src/contract.rs b/contracts/liquidity_hub/bonding-manager/src/contract.rs index 233a55ab..92dda2e8 100644 --- a/contracts/liquidity_hub/bonding-manager/src/contract.rs +++ b/contracts/liquidity_hub/bonding-manager/src/contract.rs @@ -2,9 +2,9 @@ use cosmwasm_std::{ensure, entry_point, from_json, Addr, Coin, Order, Reply, Uin use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::{get_contract_version, set_contract_version}; use cw_utils::parse_reply_execute_data; -use white_whale_std::pool_network::asset; use white_whale_std::bonding_manager::{Config, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use white_whale_std::pool_network::asset; use crate::error::ContractError; use crate::helpers::{self, validate_growth_rate}; @@ -65,15 +65,15 @@ pub fn execute( match msg { ExecuteMsg::Bond => { let asset_to_bond = helpers::validate_funds(&deps, &info)?; - commands::bond(deps, env.block.time, info, env, asset_to_bond) + commands::bond(deps, info, env, asset_to_bond) } ExecuteMsg::Unbond { asset } => { cw_utils::nonpayable(&info)?; - commands::unbond(deps, env.block.time, info, env, asset) + commands::unbond(deps, info, env, asset) } ExecuteMsg::Withdraw { denom } => { cw_utils::nonpayable(&info)?; - commands::withdraw(deps, env.block.time, info.sender, denom) + commands::withdraw(deps, info.sender, denom) } ExecuteMsg::UpdateConfig { epoch_manager_addr, @@ -94,7 +94,7 @@ pub fn execute( ExecuteMsg::FillRewards => commands::fill_rewards(deps, env, info), ExecuteMsg::Claim => commands::claim(deps, info), ExecuteMsg::EpochChangedHook { current_epoch } => { - commands::on_epoch_created(deps, env, info, current_epoch) + commands::on_epoch_created(deps, info, current_epoch) } ExecuteMsg::UpdateOwnership(action) => { cw_utils::nonpayable(&info)?; @@ -104,7 +104,7 @@ pub fn execute( } #[entry_point] -pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { QueryMsg::Config => Ok(to_json_binary(&queries::query_config(deps)?)?), QueryMsg::Bonded { address } => Ok(to_json_binary(&queries::query_bonded(deps, address)?)?), @@ -121,20 +121,29 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result Ok(to_json_binary( - &queries::query_withdrawable(deps, env.block.time, address, denom)?, + &queries::query_withdrawable(deps, address, denom)?, )?), QueryMsg::Weight { address, - timestamp, + epoch_id, global_index, } => { - // If timestamp is not provided, use current block time - let timestamp = timestamp.unwrap_or(env.block.time); + let epoch_id = if let Some(epoch_id) = epoch_id { + epoch_id + } else { + // If epoch_id is not provided, use current epoch + let config = CONFIG.load(deps.storage)?; + let current_epoch: white_whale_std::epoch_manager::epoch_manager::EpochResponse = + deps.querier.query_wasm_smart( + config.epoch_manager_addr, + &white_whale_std::epoch_manager::epoch_manager::QueryMsg::CurrentEpoch {}, + )?; + current_epoch.epoch.id + }; - // TODO: Make better timestamp handling Ok(to_json_binary(&queries::query_weight( deps, - timestamp, + epoch_id, address, global_index, )?)?) diff --git a/contracts/liquidity_hub/bonding-manager/src/queries.rs b/contracts/liquidity_hub/bonding-manager/src/queries.rs index 05eacdb2..0e0d8975 100644 --- a/contracts/liquidity_hub/bonding-manager/src/queries.rs +++ b/contracts/liquidity_hub/bonding-manager/src/queries.rs @@ -1,8 +1,9 @@ use std::collections::{HashSet, VecDeque}; -use cosmwasm_std::{Decimal, Deps, Order, StdError, StdResult, Timestamp, Uint128, Uint64}; +use cosmwasm_std::{Decimal, Deps, Order, StdError, StdResult, Uint128, Uint64}; use cw_storage_plus::Bound; +use crate::ContractError; use white_whale_std::bonding_manager::{ Bond, BondedResponse, BondingWeightResponse, Config, GlobalIndex, UnbondingResponse, WithdrawableResponse, @@ -45,7 +46,7 @@ pub(crate) fn query_bonded(deps: Deps, address: Option) -> StdResult) -> Option> { /// unbonding period and can be withdrawn. pub(crate) fn query_withdrawable( deps: Deps, - timestamp: Timestamp, address: String, denom: String, ) -> StdResult { - let config = CONFIG.load(deps.storage)?; let unbonding: StdResult> = UNBOND .prefix((&deps.api.addr_validate(address.as_str())?, &denom)) .range(deps.storage, None, None, Order::Ascending) .take(MAX_PAGE_LIMIT as usize) .collect(); + let config = CONFIG.load(deps.storage)?; + let current_epoch: white_whale_std::epoch_manager::epoch_manager::EpochResponse = + deps.querier.query_wasm_smart( + config.epoch_manager_addr, + &white_whale_std::epoch_manager::epoch_manager::QueryMsg::CurrentEpoch {}, + )?; + let mut withdrawable_amount = Uint128::zero(); for (_, bond) in unbonding? { - if timestamp.minus_nanos(config.unbonding_period.u64()) >= bond.timestamp { + if current_epoch.epoch.id.saturating_sub(bond.created_at_epoch) >= config.unbonding_period { withdrawable_amount = withdrawable_amount.checked_add(bond.asset.amount)?; } } @@ -142,7 +148,7 @@ pub(crate) fn query_withdrawable( /// Queries the current weight of the given address. pub(crate) fn query_weight( deps: Deps, - timestamp: Timestamp, + epoch_id: u64, address: String, global_index: Option, ) -> StdResult { @@ -163,11 +169,11 @@ pub(crate) fn query_weight( for (_, mut bond) in bonds? { bond.weight = get_weight( - timestamp, + epoch_id, bond.weight, bond.asset.amount, config.growth_rate, - bond.timestamp, + bond.updated_last, )?; if !unique_denoms.contains(&bond.asset.denom) { @@ -189,11 +195,11 @@ pub(crate) fn query_weight( }; global_index.weight = get_weight( - timestamp, + epoch_id, global_index.weight, global_index.bonded_amount, config.growth_rate, - global_index.timestamp, + global_index.last_updated, )?; // Represents the share of the global weight that the address has @@ -209,7 +215,7 @@ pub(crate) fn query_weight( weight: total_bond_weight, global_weight: global_index.weight, share, - timestamp, + epoch_id, }) } @@ -221,10 +227,12 @@ pub fn query_global_index(deps: Deps) -> StdResult { /// Returns the epoch that is falling out the grace period, which is the one expiring after creating /// a new epoch is created. -pub fn get_expiring_epoch(deps: Deps) -> StdResult> { +pub fn get_expiring_epoch(deps: Deps) -> Result, ContractError> { let config = CONFIG.load(deps.storage)?; // Adding 1 because we store the future epoch in the map also, so grace_period + 1 - let grace_period_plus_future_epoch = config.grace_period.u64() + 1u64; + let grace_period_plus_future_epoch = Uint64::new(config.grace_period) + .checked_add(Uint64::one())? + .u64(); // Take grace_period + 1 and then slice last one off let epochs = EPOCHS .range(deps.storage, None, None, Order::Descending) @@ -251,7 +259,9 @@ pub fn get_expiring_epoch(deps: Deps) -> StdResult> { pub fn get_claimable_epochs(deps: Deps) -> StdResult { let config = CONFIG.load(deps.storage)?; // Adding 1 because we store the future epoch in the map also, so grace_period + 1 - let grace_period = config.grace_period.u64() + 1; + let grace_period = Uint64::new(config.grace_period) + .checked_add(Uint64::one())? + .u64(); // Take grace_period + 1 and then slice last one off let mut epochs = EPOCHS .range(deps.storage, None, None, Order::Descending) diff --git a/contracts/liquidity_hub/bonding-manager/src/state.rs b/contracts/liquidity_hub/bonding-manager/src/state.rs index 6210e2fc..120ae7cb 100644 --- a/contracts/liquidity_hub/bonding-manager/src/state.rs +++ b/contracts/liquidity_hub/bonding-manager/src/state.rs @@ -1,7 +1,5 @@ use crate::ContractError; -use cosmwasm_std::{ - Addr, Decimal, Deps, DepsMut, Order, StdError, StdResult, Timestamp, Uint128, Uint64, -}; +use cosmwasm_std::{Addr, Decimal, Deps, DepsMut, Order, StdError, StdResult, Uint128}; use cw_storage_plus::{Item, Map}; use white_whale_std::bonding_manager::{Bond, Config, Epoch, GlobalIndex}; @@ -12,27 +10,27 @@ pub const CONFIG: Item = Item::new("config"); pub const BOND: Map<(&Addr, &Denom), Bond> = Map::new("bond"); pub const UNBOND: Map<(&Addr, &Denom, u64), Bond> = Map::new("unbond"); pub const GLOBAL: Item = Item::new("global"); -pub const LAST_CLAIMED_EPOCH: Map<&Addr, Uint64> = Map::new("last_claimed_epoch"); +pub const LAST_CLAIMED_EPOCH: Map<&Addr, u64> = Map::new("last_claimed_epoch"); pub const EPOCHS: Map<&[u8], Epoch> = Map::new("epochs"); /// Updates the local weight of the given address. pub fn update_local_weight( deps: &mut DepsMut, address: Addr, - timestamp: Timestamp, + current_epoch_id: u64, mut bond: Bond, ) -> Result { let config = CONFIG.load(deps.storage)?; bond.weight = get_weight( - timestamp, + current_epoch_id, bond.weight, bond.asset.amount, config.growth_rate, - bond.timestamp, + bond.updated_last, )?; - bond.timestamp = timestamp; + bond.updated_last = current_epoch_id; let denom: &String = &bond.asset.denom; @@ -45,20 +43,20 @@ pub fn update_local_weight( /// Updates the global weight of the contract. pub fn update_global_weight( deps: &mut DepsMut, - timestamp: Timestamp, + current_epoch_id: u64, mut global_index: GlobalIndex, ) -> Result { let config = CONFIG.load(deps.storage)?; global_index.weight = get_weight( - timestamp, + current_epoch_id, global_index.weight, global_index.bonded_amount, config.growth_rate, - global_index.timestamp, + global_index.last_updated, )?; - global_index.timestamp = timestamp; + global_index.last_updated = current_epoch_id; //todo remove? done outside of this function. Or remove outside GLOBAL.save(deps.storage, &global_index)?; @@ -66,21 +64,20 @@ pub fn update_global_weight( Ok(global_index) } -/// Calculates the bonding weight of the given amount for the provided timestamps. +/// Calculates the bonding weight of the given amount for the provided epochs. pub fn get_weight( - current_timestamp: Timestamp, + current_epoch_id: u64, weight: Uint128, amount: Uint128, growth_rate: Decimal, - timestamp: Timestamp, + epoch_id: u64, ) -> StdResult { - let time_factor = if timestamp == Timestamp::default() { + let time_factor = if current_epoch_id == epoch_id { Uint128::zero() } else { Uint128::from( - current_timestamp - .seconds() - .checked_sub(timestamp.seconds()) + current_epoch_id + .checked_sub(epoch_id) .ok_or_else(|| StdError::generic_err("Error calculating time_factor"))?, ) }; @@ -96,7 +93,7 @@ pub fn get_expiring_epoch(deps: Deps) -> StdResult> { // last epochs within the grace period let epochs = EPOCHS .range(deps.storage, None, None, Order::Descending) - .take(grace_period.u64() as usize) + .take(grace_period as usize) .map(|item| { let (_, epoch) = item?; Ok(epoch) @@ -105,7 +102,7 @@ pub fn get_expiring_epoch(deps: Deps) -> StdResult> { // if the epochs vector's length is the same as the grace period it means there is one epoch that // is expiring once the new one is created i.e. the last epoch in the vector - if epochs.len() == grace_period.u64() as usize { + if epochs.len() == grace_period as usize { Ok(Some(epochs.last().cloned().unwrap_or_default())) } else { // nothing is expiring yet diff --git a/contracts/liquidity_hub/bonding-manager/src/tests/bond.rs b/contracts/liquidity_hub/bonding-manager/src/tests/bond.rs index 14895e28..d4b6de33 100644 --- a/contracts/liquidity_hub/bonding-manager/src/tests/bond.rs +++ b/contracts/liquidity_hub/bonding-manager/src/tests/bond.rs @@ -72,7 +72,7 @@ fn test_bond_successfully() { weight: Uint128::new(1_000u128), global_weight: Uint128::new(1_000u128), share: Decimal::one(), - timestamp: Timestamp::from_nanos(1571883819879305533u64), + epoch_id: Timestamp::from_nanos(1571883819879305533u64), }, ); @@ -137,7 +137,7 @@ fn test_bond_successfully() { weight: Uint128::new(5_000u128), global_weight: Uint128::new(950_409_000u128), share: Decimal::from_ratio(5_000u128, 950_409_000u128), - timestamp: Timestamp::from_nanos(1572013419879305533u64), + epoch_id: Timestamp::from_nanos(1572013419879305533u64), }, ) .query_bonded(None, |res| { @@ -170,7 +170,7 @@ fn test_bond_successfully() { weight: Uint128::new(734_404_000u128), global_weight: Uint128::new(1_728_009_000u128), share: Decimal::from_ratio(734_404_000u128, 1_728_009_000u128), - timestamp: Timestamp::from_nanos(1572099819879305533u64), + epoch_id: Timestamp::from_nanos(1572099819879305533u64), }, ) .assert_bonding_weight_response( @@ -180,7 +180,7 @@ fn test_bond_successfully() { weight: Uint128::new(432_005_000u128), global_weight: Uint128::new(1_728_009_000u128), share: Decimal::from_ratio(432_005_000u128, 1_728_009_000u128), - timestamp: Timestamp::from_nanos(1572099819879305533u64), + epoch_id: Timestamp::from_nanos(1572099819879305533u64), }, ) .query_bonded(None, |result| { diff --git a/contracts/liquidity_hub/bonding-manager/src/tests/suite.rs b/contracts/liquidity_hub/bonding-manager/src/tests/suite.rs index 6ea88c28..3eb472bd 100644 --- a/contracts/liquidity_hub/bonding-manager/src/tests/suite.rs +++ b/contracts/liquidity_hub/bonding-manager/src/tests/suite.rs @@ -456,7 +456,7 @@ impl TestingSuite { &self.bonding_manager_addr, &QueryMsg::Weight { address, - timestamp: Some(self.app.block_info().time), + epoch_id: Some(self.app.block_info().time), global_index: None, }, ) diff --git a/packages/white-whale-std/src/bonding_manager.rs b/packages/white-whale-std/src/bonding_manager.rs index 355667aa..953a2404 100644 --- a/packages/white-whale-std/src/bonding_manager.rs +++ b/packages/white-whale-std/src/bonding_manager.rs @@ -2,7 +2,7 @@ use crate::epoch_manager::epoch_manager::Epoch as EpochV2; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{ - to_json_binary, Addr, Coin, CosmosMsg, Decimal, StdResult, Timestamp, Uint128, Uint64, WasmMsg, + to_json_binary, Addr, Coin, CosmosMsg, Decimal, StdResult, Timestamp, Uint128, WasmMsg, }; use cw_ownable::{cw_ownable_execute, cw_ownable_query}; @@ -16,21 +16,22 @@ pub struct Config { pub distribution_denom: String, /// Unbonding period in nanoseconds. The time that needs to pass before an unbonded position can /// be withdrawn - pub unbonding_period: Uint64, + pub unbonding_period: u64, /// A fraction that controls the effect of time on the weight of a bond. If the growth rate is set /// to zero, time will have no impact on the weight. pub growth_rate: Decimal, /// Denom of the asset to be bonded. Can't only be set at instantiation. pub bonding_assets: Vec, - /// The duration of the grace period in epochs, i.e. how many expired epochs can be claimed - pub grace_period: Uint64, + /// Grace period the maximum age of a epoch bucket before it's considered expired and fees + /// are forwarded from it + pub grace_period: u64, } #[cw_serde] #[derive(Default)] pub struct Epoch { // Epoch identifier - pub id: Uint64, + pub id: u64, // Epoch start time pub start_time: Timestamp, // Initial fees to be distributed in this epoch. @@ -48,9 +49,9 @@ pub struct Bond { /// The amount of bonded tokens. pub asset: Coin, /// The epoch id at which the Bond was created. - pub created_at_epoch: Uint64, - /// The timestamp at which the bond was done. - pub timestamp: Timestamp, + pub created_at_epoch: u64, + /// The epoch id at which the bond was last time updated. + pub updated_last: u64, /// The weight of the bond at the given block height. pub weight: Uint128, } @@ -63,7 +64,7 @@ impl Default for Bond { amount: Uint128::zero(), }, created_at_epoch: Default::default(), - timestamp: Timestamp::default(), + updated_last: Default::default(), weight: Uint128::zero(), } } @@ -76,8 +77,8 @@ pub struct GlobalIndex { pub bonded_amount: Uint128, /// Assets that are bonded in the contract. pub bonded_assets: Vec, - /// The timestamp at which the total bond was registered. - pub timestamp: Timestamp, + /// The epoch id at which the total bond was updated. + pub last_updated: u64, /// The total weight of the bond at the given block height. pub weight: Uint128, } @@ -86,15 +87,16 @@ pub struct GlobalIndex { pub struct InstantiateMsg { /// Denom to be swapped to and rewarded pub distribution_denom: String, - /// Unbonding period in nanoseconds. The time that needs to pass before an unbonded position can + /// Unbonding period in epochs. The time (in epochs) that needs to pass before an unbonded position can /// be withdrawn - pub unbonding_period: Uint64, + pub unbonding_period: u64, /// Weight grow rate. Needs to be between 0 and 1. pub growth_rate: Decimal, /// [String] denoms of the assets that can be bonded. pub bonding_assets: Vec, - /// Grace period the maximum age of a bucket before fees are forwarded from it - pub grace_period: Uint64, + /// Grace period the maximum age of a epoch bucket before it's considered expired and fees + /// are forwarded from it + pub grace_period: u64, /// The epoch manager contract pub epoch_manager_addr: String, } @@ -126,7 +128,7 @@ pub enum ExecuteMsg { /// The new pool manager address. pool_manager_addr: Option, /// The unbonding period. - unbonding_period: Option, + unbonding_period: Option, /// The new growth rate. growth_rate: Option, }, @@ -190,7 +192,7 @@ pub enum QueryMsg { /// The address to check for weight. address: String, /// The timestamp to check for weight. If none is provided, the current block time is used. - timestamp: Option, + epoch_id: Option, /// The global index to check for weight. If none is provided, the current global index is used. global_index: Option, }, @@ -221,7 +223,7 @@ pub struct BondedResponse { pub bonded_assets: Vec, /// If Some, the epoch id at which the user/address bonded first time. None is used when this /// Response is used to check the bonded assets in the contract. - pub first_bonded_epoch_id: Option, + pub first_bonded_epoch_id: Option, } /// Response for the Unbonding query @@ -251,8 +253,8 @@ pub struct BondingWeightResponse { pub global_weight: Uint128, /// The share the address has of the rewards at the particular timestamp. pub share: Decimal, - /// The timestamp at which the weight was calculated. - pub timestamp: Timestamp, + /// The epoch id at which the weight was calculated. + pub epoch_id: u64, } /// Creates a message to fill rewards on the whale lair contract.