Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge redist with base #1009

Merged
merged 31 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
541392d
farm and farm staking refactor
psorinionut Nov 20, 2024
e233615
fixed unit tests
psorinionut Nov 20, 2024
6b1fbc1
added permissions hub module
psorinionut Nov 20, 2024
6d21325
unit tests fix
psorinionut Nov 20, 2024
dcb6407
farm with locked rewards unit tests fix
psorinionut Nov 20, 2024
a2f526f
added OriginalOwnerHelperModule
psorinionut Nov 20, 2024
ff2d08c
add readme for permissions hub SC + onBehalf features
psorinionut Dec 6, 2024
23c1adb
exitOnBehalf readme
psorinionut Dec 11, 2024
f188905
bump mx-sc-actions version
BiancaIalangi Jan 10, 2025
a2445d3
Merge pull request #989 from multiversx/on-behalf-features-readme
ovidiuolteanu Jan 10, 2025
e934c85
Merge pull request #993 from multiversx/bump-mx-sc-actions
psorinionut Jan 10, 2025
a31361e
Merge pull request #967 from multiversx/farm-on-behalf-features
psorinionut Jan 10, 2025
16aa2a7
updated cargo locks for v3.0.2
psorinionut Jan 10, 2025
58a7e74
Merge pull request #995 from multiversx/v3.0.2-cargo-locks
psorinionut Jan 10, 2025
6ff91e7
audit fixes + unit tests
psorinionut Jan 13, 2025
c755d38
clippy fix
psorinionut Jan 13, 2025
ca2aef1
allow multiple payments for claim onBehalf
psorinionut Jan 13, 2025
2f788d1
small code changes
psorinionut Jan 14, 2025
045e4ac
add migration code to farm staking onBehalf
psorinionut Jan 16, 2025
420269a
Merge pull request #996 from multiversx/on-behalf-feature-audit-fixes
psorinionut Jan 16, 2025
f2f4324
OnBehalf feature code optimizations
psorinionut Feb 18, 2025
c31c2b6
Github actions update
psorinionut Feb 19, 2025
b41ac09
Claim on behalf legacy tokens check
psorinionut Feb 19, 2025
8aa7bb9
Merge pull request #1005 from multiversx/v3.0.2-github-actions-update
psorinionut Feb 19, 2025
832436b
Merge branch 'rc/v3.0.2' into claim-onbehalf-legacy-tokens-check
psorinionut Feb 19, 2025
2353344
Merge branch 'rc/v3.0.2' into onBehalf-feature-code-optimization
ovidiuolteanu Feb 20, 2025
ec7acf3
Update common/modules/original_owner_helper/src/lib.rs
psorinionut Feb 20, 2025
9d00699
Merge pull request #1003 from multiversx/onBehalf-feature-code-optimi…
ovidiuolteanu Feb 20, 2025
9b3a456
Merge branch 'rc/v3.0.2' into claim-onbehalf-legacy-tokens-check
ovidiuolteanu Feb 20, 2025
9df990a
Merge pull request #1006 from multiversx/claim-onbehalf-legacy-tokens…
ovidiuolteanu Feb 20, 2025
ca8594b
Merge branch 'rc/v3.0.2' into merge-redist-with-base
dorin-iancu Feb 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ permissions:
jobs:
contracts:
name: Contracts
uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@v3.3.1
uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@v4.2.2
with:
rust-toolchain: nightly-2024-05-22
rust-toolchain: stable
coverage-args: --ignore-filename-regex='/.cargo/git' --output ./coverage.md
secrets:
token: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ permissions:

jobs:
build:
uses: multiversx/mx-sc-actions/.github/workflows/reproducible-build.yml@v3.3.1
uses: multiversx/mx-sc-actions/.github/workflows/reproducible-build.yml@v4.2.2
with:
image_tag: v7.0.0
attach_to_existing_release: true
23 changes: 23 additions & 0 deletions Cargo.lock

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

7 changes: 7 additions & 0 deletions common/common_structs/src/farm_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ pub trait FarmToken<M: ManagedTypeApi> {
fn get_compounded_rewards(&self) -> BigUint<M>;

fn get_initial_farming_tokens(&self) -> BigUint<M>;

fn get_original_owner(&self) -> ManagedAddress<M>;
}

impl<M: ManagedTypeApi> FarmToken<M> for FarmTokenAttributes<M> {
Expand All @@ -97,4 +99,9 @@ impl<M: ManagedTypeApi> FarmToken<M> for FarmTokenAttributes<M> {
fn get_initial_farming_tokens(&self) -> BigUint<M> {
&self.current_farm_amount - &self.compounded_reward
}

#[inline]
fn get_original_owner(&self) -> ManagedAddress<M> {
self.original_owner.clone()
}
}
15 changes: 15 additions & 0 deletions common/modules/original_owner_helper/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "original_owner_helper"
version = "0.0.0"
authors = ["MultiversX <[email protected]>"]
edition = "2021"

[lib]
path = "src/lib.rs"

[dependencies.multiversx-sc]
version = "=0.53.2"
features = ["esdt-token-payment-legacy-decode"]

[dependencies.common_structs]
path = "../../common_structs"
75 changes: 75 additions & 0 deletions common/modules/original_owner_helper/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#![no_std]

multiversx_sc::imports!();

use common_structs::{FarmToken, PaymentsVec};

#[multiversx_sc::module]
pub trait OriginalOwnerHelperModule {
fn get_claim_original_owner<T: FarmToken<Self::Api> + TopDecode>(
&self,
farm_token_mapper: &NonFungibleTokenMapper,
) -> ManagedAddress {
let payments = self.call_value().all_esdt_transfers();
let farm_token_id = farm_token_mapper.get_token_id();

let mut opt_original_owner = None;
for payment in payments.into_iter() {
require!(
payment.token_identifier == farm_token_id,
"Invalid payment token"
);

let attributes: T = farm_token_mapper.get_token_attributes(payment.token_nonce);
let payment_original_owner = attributes.get_original_owner();

require!(
!payment_original_owner.is_zero(),
"Cannot claim rewards on behalf of legacy positions"
);

match opt_original_owner {
Some(ref original_owner) => {
require!(
*original_owner == payment_original_owner,
"Original owner is not the same for all payments"
);
}
None => opt_original_owner = Some(payment_original_owner),
}
}

require!(
opt_original_owner.is_some(),
"Original owner could not be identified"
);

unsafe { opt_original_owner.unwrap_unchecked() }
}

fn check_additional_payments_original_owner<T: FarmToken<Self::Api> + TopDecode>(
&self,
user: &ManagedAddress,
payments: &PaymentsVec<Self::Api>,
farm_token_mapper: &NonFungibleTokenMapper,
) {
if payments.len() == 1 {
return;
}

let farm_token_id = farm_token_mapper.get_token_id();
for payment in payments.into_iter() {
if payment.token_identifier != farm_token_id {
continue;
}

let attributes: T = farm_token_mapper.get_token_attributes(payment.token_nonce);
let payment_original_owner = attributes.get_original_owner();

require!(
user == &payment_original_owner,
"Provided address is not the same as the original owner"
);
}
}
}
15 changes: 15 additions & 0 deletions common/modules/permissions_hub_module/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "permissions_hub_module"
version = "0.0.0"
authors = ["MultiversX <[email protected]>"]
edition = "2021"

[lib]
path = "src/permissions_hub_module.rs"

[dependencies.permissions-hub]
path = "../../../dex/permissions-hub"

[dependencies.multiversx-sc]
version = "=0.53.2"
features = ["esdt-token-payment-legacy-decode"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#![no_std]

multiversx_sc::imports!();
multiversx_sc::derive_imports!();

#[multiversx_sc::module]
pub trait PermissionsHubModule {
fn require_user_whitelisted(&self, user: &ManagedAddress, authorized_address: &ManagedAddress) {
let permissions_hub_address = self.permissions_hub_address().get();
let is_whitelisted: bool = self
.permissions_hub_proxy(permissions_hub_address)
.is_whitelisted(user, authorized_address)
.execute_on_dest_context();

require!(
is_whitelisted,
"Caller is not whitelisted by the user or is blacklisted"
);
}

#[only_owner]
#[endpoint(setPermissionsHubAddress)]
fn set_permissions_hub_address(&self, address: ManagedAddress) {
self.permissions_hub_address().set(&address);
}

#[proxy]
fn permissions_hub_proxy(
&self,
sc_address: ManagedAddress,
) -> permissions_hub::Proxy<Self::Api>;

#[storage_mapper("permissionsHubAddress")]
fn permissions_hub_address(&self) -> SingleValueMapper<ManagedAddress>;
}
6 changes: 6 additions & 0 deletions dex/farm-with-locked-rewards/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ path = "../../common/modules/utils"
[dependencies.permissions_module]
path = "../../common/modules/permissions_module"

[dependencies.permissions_hub_module]
path = "../../common/modules/permissions_hub_module"

[dependencies.original_owner_helper]
path = "../../common/modules/original_owner_helper"

[dependencies.sc_whitelist_module]
path = "../../common/modules/sc_whitelist_module"

Expand Down
69 changes: 69 additions & 0 deletions dex/farm-with-locked-rewards/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,72 @@ The interaction scripts for this contract are located in the dex subdirectory of
## Deployment

The deployment of this contract is done using interaction scripts and it is managed by its admin.

# Farm With Locked Rewards OnBehalf Operations

## Abstract

The Farm With Locked Rewards OnBehalf operations extend the Farm With Locked Rewards smart contract with the ability to allow whitelisted contracts to perform actions on behalf of users, enabling enhanced protocol composability while maintaining security through integration with the Permissions Hub.

## Introduction

This module allows third-party contracts to perform farm operations on behalf of users, after being explicitly whitelisted through the Permissions Hub. Users maintain full control over their assets by managing contract permissions, while protocols can build more complex DeFi interactions.

## Endpoints

### enterFarmOnBehalf

```rust
#[payable("*")]
#[endpoint(enterFarmOnBehalf)]
fn enter_farm_on_behalf(&self, user: ManagedAddress) -> EnterFarmResultType<Self::Api>
```

The enterFarmOnBehalf function allows whitelisted contracts to enter farm positions on behalf of users. It receives several arguments:

- __user__ - The address of the user for whom the operation is being performed. This address must have whitelisted the caller contract through the Permissions Hub.
- __payment__ - The tokens to be used are received as payment in the transaction.

The function performs the following steps:
1. Validates that the caller is whitelisted by the user through Permissions Hub
2. Processes the farming tokens payment
3. Claims any pending boosted rewards for the original owner
4. Performs the enter farm operation on behalf of the original owner
5. Sends the new farm token to the caller
6. Sends the locked rewards, if any, to the original owner
7. Updates energy and progress for the original owner

### claimRewardsOnBehalf

```rust
#[payable("*")]
#[endpoint(claimRewardsOnBehalf)]
fn claim_rewards_on_behalf(&self) -> ClaimRewardsResultType<Self::Api>
```

The claimRewardsOnBehalf function enables whitelisted contracts to claim rewards on behalf of the users. This function does not require any address parameter, as the original owner is read from the farm position metadata. The operation requires:

- __payment__ - The farm token must be received as payment in the transaction.

The function performs these steps:
1. Processes the farm token payment
2. Extracts the original owner from the farm token attributes
3. Validates that the caller is whitelisted by the original owner
4. Claims and sends locked rewards to the original owner
5. Sends the new farm token to the caller

## exitOnBehalf
The exit operation remains under the direct control of the position owner to ensure maximum security. When third-party contracts interact with farming positions through onBehalf operations, they receive and hold the position tokens. These tokens maintain the original owner information in their attributes, protecting the user's ownership rights. To exit their position, users must first reclaim their position tokens from the third-party contract through that protocol's specific mechanisms. Once users have regained control of their position tokens, they can perform the standard exit operation directly through the specific xExchange contract.
This design ensures users maintain ultimate control over their funds while allowing protocols to build complex DeFi interactions.

## Storage

The contract relies on the Permissions Hub for permission management, thus no additional storage, other than the one holding the Permissions Hub SC address, is required. All whitelisting data is managed through the Permissions Hub contract.

## Deployment

The onBehalf features are part of the core farm contract and require:

1. A deployed Permissions Hub contract
2. Configuration of the Permissions Hub address in the farm contract
3. User whitelisting of contracts that will perform onBehalf operations
Loading
Loading