diff --git a/Forc.lock b/Forc.lock index b5cdbf67..ae4df98f 100644 --- a/Forc.lock +++ b/Forc.lock @@ -38,6 +38,22 @@ dependencies = [ "std", ] +[[package]] +name = "rewards" +source = "member" +dependencies = [ + "market_abi", + "rewards_abi", + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.6.1#792639cdf391565e6e6a02482ea8a46d9604a6f5", + "std", + "sway_libs", +] + +[[package]] +name = "rewards_abi" +source = "member" +dependencies = ["std"] + [[package]] name = "src-20" source = "member" diff --git a/Forc.toml b/Forc.toml index c7e84b10..c032dc67 100644 --- a/Forc.toml +++ b/Forc.toml @@ -2,8 +2,10 @@ members = [ # ABIs "abis/market_abi", + "abis/rewards_abi", # Contracts "contracts/market", + "contracts/rewards", "contracts/src-20", "contracts/token", "contracts/pyth-mock", diff --git a/abis/rewards_abi/Forc.toml b/abis/rewards_abi/Forc.toml new file mode 100644 index 00000000..022c6a8a --- /dev/null +++ b/abis/rewards_abi/Forc.toml @@ -0,0 +1,6 @@ +[project] +entry = "abi.sw" +license = "Apache-2.0" +name = "rewards_abi" + +[dependencies] diff --git a/abis/rewards_abi/src/abi.sw b/abis/rewards_abi/src/abi.sw new file mode 100644 index 00000000..9789a24c --- /dev/null +++ b/abis/rewards_abi/src/abi.sw @@ -0,0 +1,52 @@ +library; + +pub mod structs; + +use structs::*; + +abi Rewards { + // Get version of the smart contract + fn get_version() -> u8; + + // # 0. Activate contract + #[storage(write)] + fn activate_contract(owner: Identity); + + // # 1. Set the reward configs to rewardConfig for specific market instance + #[storage(write)] + fn set_reward_config_with_multiplier(market: ContractId, token: AssetId, multiplier: u256); + + // # 2. Set the reward token for a swaylend market instance + #[storage(write)] + fn set_reward_config(market: ContractId, token: AssetId); + + // # 3. Set the rewards claimed for a list of users - this is for management only + // the rewards claimed are updated in claimInternal function + #[storage(write)] + fn set_rewards_claimed(market: ContractId, users: Vec, claimed_amounts: Vec); + + // # 4. Withdraw tokens from the contract + #[storage(read)] + fn withdraw_token(token: AssetId, to: Identity, amount: u256); + + // # 5. Transfers the governor rights to a new address + #[storage(write)] + fn transfer_governor(new_governor: Identity); + + // # 6. Calculates the amount of a reward token owed to an account + #[storage(read)] + fn get_reward_owed(market: ContractId, account: Identity) -> RewardOwed; + + // # 7. Claim rewards of token type from a swaylend market instance to owner address + // This one calls internal claimInternal + #[storage(read, write)] + fn claim(market: ContractId, src: Identity, should_accrue: bool); + + // # 8. Claim rewards of token type from a swaylend market instance to a target address + #[storage(read, write)] + fn claim_to(market: ContractId, src: Identity, to: Identity, should_accrue: bool); + + // # 9. Set ownership to zero address + #[storage(write)] + fn renounce_ownership(); +} diff --git a/abis/rewards_abi/src/structs.sw b/abis/rewards_abi/src/structs.sw new file mode 100644 index 00000000..595254ba --- /dev/null +++ b/abis/rewards_abi/src/structs.sw @@ -0,0 +1,44 @@ +library; + +/// This struct contains config details for a specific market +pub struct RewardConfiguration { + /// Token to use for compounding rewards + token: AssetId, + rescale_factor: u64, + should_upscale: bool, + multiplier: u256, +} + +impl RewardConfiguration { + pub fn default() -> Self { + RewardConfiguration { + token: AssetId::zero(), + rescale_factor: 0, + should_upscale: false, + multiplier: 0, + } + } +} + +pub struct RewardOwed { + token: AssetId, + owed: u256, +} + +impl RewardOwed { + pub fn default() -> Self { + RewardOwed { + token: AssetId::zero(), + owed: 0, + } + } +} + +pub enum Error { + AlreadyConfigured: (), + BadData: (), + InvalidUInt64: (), + NotPermitted: (), + NotSupported: (), + TransferOutFailed: (), +} diff --git a/contracts/rewards/.gitignore b/contracts/rewards/.gitignore new file mode 100644 index 00000000..77d3844f --- /dev/null +++ b/contracts/rewards/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/contracts/rewards/Forc.toml b/contracts/rewards/Forc.toml new file mode 100644 index 00000000..0201719d --- /dev/null +++ b/contracts/rewards/Forc.toml @@ -0,0 +1,11 @@ +[project] +authors = ["Urban Vidovič"] +entry = "main.sw" +license = "Apache-2.0" +name = "rewards" + +[dependencies] +market_abi = { path = "../../abis/market_abi" } +rewards_abi = { path = "../../abis/rewards_abi" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.1" } +sway_libs = { git = "https://github.com/FuelLabs/sway-libs", tag = "v0.24.0" } diff --git a/contracts/rewards/src/events.sw b/contracts/rewards/src/events.sw new file mode 100644 index 00000000..32842069 --- /dev/null +++ b/contracts/rewards/src/events.sw @@ -0,0 +1,20 @@ +library; + + +pub struct GovernorTransferred { + pub old_governor: Identity, + pub new_governor: Identity, +} + +pub struct RewardsClaimedSet { + pub user: Identity, + pub market: ContractId, + pub amount: u256, +} + +pub struct RewardsClaimed { + pub src: Identity, + pub recipient: Identity, + pub token: AssetId, + pub amount: u256, +} diff --git a/contracts/rewards/src/main.sw b/contracts/rewards/src/main.sw new file mode 100644 index 00000000..522166ca --- /dev/null +++ b/contracts/rewards/src/main.sw @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: MIT + +contract; + +// +// @title Swaylend's Market Contract +// @notice An efficient monolithic money market protocol +// @author Reserve Labs LTD +// + +mod events; + +use events::*; +use market_abi::{Market, structs::*,}; +use rewards_abi::{Rewards, structs::*,}; +use standards::src5::{SRC5, State}; +use sway_libs::ownership::*; + +// version of the smart contract +const VERSION: u8 = 1_u8; + +impl Rewards for Contract { + // Get version of the smart contract + fn get_version() -> u8 { + VERSION + } + + // # 0. Activate contract + #[storage(write)] + fn activate_contract(owner: Identity) { + initialize_ownership(owner); + } + + // # 1. Set the reward configs to rewardConfig for specific market instance + #[storage(write)] + fn set_reward_config_with_multiplier(market: ContractId, token: AssetId, multiplier: u256) {} + + // # 2. Set the reward token for a swaylend market instance + #[storage(write)] + fn set_reward_config(market: ContractId, token: AssetId) {} + + // # 3. Set the rewards claimed for a list of users - this is for management only + // the rewards claimed are updated in claimInternal function + #[storage(write)] + fn set_rewards_claimed(market: ContractId, users: Vec, claimed_amounts: Vec) {} + + // # 4. Withdraw tokens from the contract + #[storage(read)] + fn withdraw_token(token: AssetId, to: Identity, amount: u256) {} + + // # 5. Transfers the governor rights to a new address + #[storage(write)] + fn transfer_governor(new_governor: Identity) {} + + // # 6. Calculates the amount of a reward token owed to an account + #[storage(read)] + fn get_reward_owed(market: ContractId, account: Identity) -> RewardOwed { + RewardOwed::default() + } + + // # 7. Claim rewards of token type from a swaylend market instance to owner address + // This one calls internal claimInternal + #[storage(read, write)] + fn claim(market: ContractId, src: Identity, should_accrue: bool) {} + + // # 8. Claim rewards of token type from a swaylend market instance to a target address + #[storage(read, write)] + fn claim_to(market: ContractId, src: Identity, to: Identity, should_accrue: bool) {} + + // # 9. Set ownership to zero address + #[storage(write)] + fn renounce_ownership() {} +} + +impl SRC5 for Contract { + #[storage(read)] + fn owner() -> State { + _owner() + } +} + +// Claim to, assuming permitted +fn claim_internal(market: ContractId, src: Identity, to: Identity, should_accrue: bool) {} + +// Calculates the reward accrued for an account on a Comet deployment +fn get_reward_accrued(market: ContractId, account: Identity, config: RewardConfiguration) -> u256 { + u256::zero() +} + +// Safe ERC20 transfer out +fn transfer_out(token: AssetId, to: Identity, amount: u256) {}