Skip to content

Commit

Permalink
Merge pull request #921 from multiversx/simple-lock-legacy-contract
Browse files Browse the repository at this point in the history
Simple lock legacy contract
  • Loading branch information
psorinionut authored May 29, 2024
2 parents 4c1d701 + 04eff5a commit c4d11a9
Show file tree
Hide file tree
Showing 29 changed files with 955 additions and 971 deletions.
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.1.0
uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@v3.2.0
with:
rust-toolchain: nightly-2023-12-11
rust-toolchain: nightly-2024-05-22
coverage-args: --ignore-filename-regex='/.cargo/git' --output ./coverage.md
secrets:
token: ${{ secrets.GITHUB_TOKEN }}
14 changes: 14 additions & 0 deletions .github/workflows/on_pull_request_build_contracts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: On pull request, build contracts

on:
pull_request:

permissions:
contents: write

jobs:
build:
uses: multiversx/mx-sc-actions/.github/workflows/[email protected]
with:
image_tag: v7.0.0
package_whole_project_src: true
4 changes: 2 additions & 2 deletions .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@v2.3.5
uses: multiversx/mx-sc-actions/.github/workflows/reproducible-build.yml@v3.2.0
with:
image_tag: v6.0.0
image_tag: v7.0.0
attach_to_existing_release: true
25 changes: 12 additions & 13 deletions Cargo.lock

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

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ members = [
"farm-staking/metabonding-staking",
"farm-staking/metabonding-staking/meta",

"legacy-contracts/simple-lock-legacy",
"legacy-contracts/simple-lock-legacy/meta",

"locked-asset/",
"locked-asset/distribution",
"locked-asset/distribution/meta",
Expand All @@ -50,8 +53,6 @@ members = [
"locked-asset/factory/meta",
"locked-asset/simple-lock",
"locked-asset/simple-lock/meta",
"locked-asset/simple-lock-whitelist",
"locked-asset/simple-lock-whitelist/meta",
"locked-asset/energy-factory",
"locked-asset/energy-factory/meta",
"locked-asset/token-unstake",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
[package]
name = "simple-lock-whitelist"
name = "simple-lock-legacy"
version = "0.0.0"
authors = ["Dorin Iancu <dorin.iancu@multiversx.com>"]
authors = ["MultiversX <contact@multiversx.com>"]
edition = "2021"
publish = false

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

[dependencies.simple-lock]
path = "../simple-lock"

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

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

[dependencies.multiversx-sc-modules]
version = "=0.48.1"

[dependencies.common_structs]
path = "../../common/common_structs"

[dev-dependencies]
num-bigint = "0.4.2"
num-traits = "0.2"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[package]
name = "simple-lock-whitelist-meta"
name = "simple-lock-legacy-meta"
version = "0.0.0"
edition = "2021"
publish = false
authors = ["Dorin Iancu <dorin.iancu@multiversx.com>"]
authors = ["MultiversX <contact@multiversx.com>"]

[dependencies.simple-lock-whitelist]
[dependencies.simple-lock-legacy]
path = ".."

[dependencies.multiversx-sc-meta]
Expand Down
3 changes: 3 additions & 0 deletions legacy-contracts/simple-lock-legacy/meta/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
multiversx_sc_meta::cli_main::<simple_lock_legacy::AbiProvider>();
}
61 changes: 61 additions & 0 deletions legacy-contracts/simple-lock-legacy/src/basic_lock_unlock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
multiversx_sc::imports!();

use crate::{
error_messages::{CANNOT_UNLOCK_YET_ERR_MSG, NO_PAYMENT_ERR_MSG},
locked_token::LockedTokenAttributes,
};

#[multiversx_sc::module]
pub trait BasicLockUnlock:
crate::locked_token::LockedTokenModule
{
fn unlock_and_send(
&self,
to: &ManagedAddress,
payment: EsdtTokenPayment<Self::Api>,
) -> EgldOrEsdtTokenPayment<Self::Api> {
let out_payment = self.unlock_tokens(payment);
self.send().direct(
to,
&out_payment.token_identifier,
out_payment.token_nonce,
&out_payment.amount,
);

out_payment
}

fn unlock_tokens(
&self,
payment: EsdtTokenPayment<Self::Api>,
) -> EgldOrEsdtTokenPayment<Self::Api> {
let locked_token_mapper = self.locked_token();
locked_token_mapper.require_same_token(&payment.token_identifier);

let attributes: LockedTokenAttributes<Self::Api> =
locked_token_mapper.get_token_attributes(payment.token_nonce);
let current_epoch = self.blockchain().get_block_epoch();
require!(
current_epoch >= attributes.unlock_epoch,
CANNOT_UNLOCK_YET_ERR_MSG
);

locked_token_mapper.nft_burn(payment.token_nonce, &payment.amount);

self.unlock_tokens_unchecked(payment, &attributes)
}

fn unlock_tokens_unchecked(
&self,
payment: EsdtTokenPayment<Self::Api>,
attributes: &LockedTokenAttributes<Self::Api>,
) -> EgldOrEsdtTokenPayment<Self::Api> {
require!(payment.amount > 0, NO_PAYMENT_ERR_MSG);

EgldOrEsdtTokenPayment::new(
attributes.original_token_id.clone(),
attributes.original_token_nonce,
payment.amount,
)
}
}
2 changes: 2 additions & 0 deletions legacy-contracts/simple-lock-legacy/src/error_messages.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub static NO_PAYMENT_ERR_MSG: &[u8] = b"No payment";
pub static CANNOT_UNLOCK_YET_ERR_MSG: &[u8] = b"Cannot unlock yet";
41 changes: 41 additions & 0 deletions legacy-contracts/simple-lock-legacy/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#![no_std]

multiversx_sc::imports!();

pub mod basic_lock_unlock;
pub mod error_messages;
pub mod locked_token;
pub mod proxy_farm;
pub mod proxy_lp;

#[multiversx_sc::contract]
pub trait SimpleLockLegacy:
basic_lock_unlock::BasicLockUnlock
+ locked_token::LockedTokenModule
+ proxy_lp::ProxyLpModule
+ proxy_farm::ProxyFarmModule
{
#[init]
fn init(&self) {}

#[upgrade]
fn upgrade(&self) {}

#[payable("*")]
#[endpoint(unlockTokens)]
fn unlock_tokens_endpoint(
&self,
opt_destination: OptionalValue<ManagedAddress>,
) -> EgldOrEsdtTokenPayment<Self::Api> {
let payment = self.call_value().single_esdt();
let dest_address = self.dest_from_optional(opt_destination);
self.unlock_and_send(&dest_address, payment)
}

fn dest_from_optional(&self, opt_destination: OptionalValue<ManagedAddress>) -> ManagedAddress {
match opt_destination {
OptionalValue::Some(dest) => dest,
OptionalValue::None => self.blockchain().get_caller(),
}
}
}
16 changes: 16 additions & 0 deletions legacy-contracts/simple-lock-legacy/src/locked_token.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
multiversx_sc::imports!();
multiversx_sc::derive_imports!();

#[derive(TypeAbi, TopEncode, TopDecode, NestedDecode, NestedEncode, PartialEq, Debug, Clone)]
pub struct LockedTokenAttributes<M: ManagedTypeApi> {
pub original_token_id: EgldOrEsdtTokenIdentifier<M>,
pub original_token_nonce: u64,
pub unlock_epoch: u64,
}

#[multiversx_sc::module]
pub trait LockedTokenModule {
#[view(getLockedTokenId)]
#[storage_mapper("lockedTokenId")]
fn locked_token(&self) -> NonFungibleTokenMapper;
}
91 changes: 91 additions & 0 deletions legacy-contracts/simple-lock-legacy/src/proxy_farm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
multiversx_sc::imports!();
multiversx_sc::derive_imports!();

use crate::error_messages::*;

#[derive(
TypeAbi, TopEncode, TopDecode, NestedEncode, NestedDecode, PartialEq, Debug, Clone, Copy,
)]
pub enum FarmType {
SimpleFarm,
FarmWithLockedRewards,
}

#[derive(TypeAbi, TopEncode, TopDecode, NestedEncode, NestedDecode, PartialEq, Debug)]
pub struct FarmProxyTokenAttributes<M: ManagedTypeApi> {
pub farm_type: FarmType,
pub farm_token_id: TokenIdentifier<M>,
pub farm_token_nonce: u64,
pub farming_token_id: TokenIdentifier<M>,
pub farming_token_locked_nonce: u64,
}

#[multiversx_sc::module]
pub trait ProxyFarmModule:
crate::locked_token::LockedTokenModule + crate::proxy_lp::ProxyLpModule
{
/// Output payments: the underlying farm tokens
#[payable("*")]
#[endpoint(exitFarmLockedToken)]
fn exit_farm_locked_token(&self) -> EsdtTokenPayment {
let payment: EsdtTokenPayment<Self::Api> = self.call_value().single_esdt();
let caller = self.blockchain().get_caller();

let farm_proxy_token_attributes: FarmProxyTokenAttributes<Self::Api> =
self.validate_payment_and_get_farm_proxy_token_attributes(&payment);

let _ = self.check_and_get_unlocked_lp_token(
&self.lp_proxy_token().get_token_id(),
farm_proxy_token_attributes.farming_token_locked_nonce,
);

self.send().esdt_local_burn(
&self.lp_proxy_token().get_token_id(),
farm_proxy_token_attributes.farming_token_locked_nonce,
&payment.amount,
);

let output_token_payment = EsdtTokenPayment::new(
farm_proxy_token_attributes.farm_token_id,
farm_proxy_token_attributes.farm_token_nonce,
payment.amount,
);

self.send().direct_esdt(
&caller,
&output_token_payment.token_identifier,
output_token_payment.token_nonce,
&output_token_payment.amount,
);

output_token_payment
}

/// Output payments: the underlying farm tokens
#[payable("*")]
#[endpoint(farmClaimRewardsLockedToken)]
fn farm_claim_rewards_locked_token(&self) -> EsdtTokenPayment {
self.exit_farm_locked_token()
}

fn validate_payment_and_get_farm_proxy_token_attributes(
&self,
payment: &EsdtTokenPayment<Self::Api>,
) -> FarmProxyTokenAttributes<Self::Api> {
require!(payment.amount > 0, NO_PAYMENT_ERR_MSG);

let farm_proxy_token_mapper = self.farm_proxy_token();
farm_proxy_token_mapper.require_same_token(&payment.token_identifier);

let farm_proxy_token_attributes: FarmProxyTokenAttributes<Self::Api> =
farm_proxy_token_mapper.get_token_attributes(payment.token_nonce);

farm_proxy_token_mapper.nft_burn(payment.token_nonce, &payment.amount);

farm_proxy_token_attributes
}

#[view(getFarmProxyTokenId)]
#[storage_mapper("farmProxyTokenId")]
fn farm_proxy_token(&self) -> NonFungibleTokenMapper;
}
Loading

0 comments on commit c4d11a9

Please sign in to comment.