multiversx_wegld_swap_sc/
wegld.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#![no_std]

multiversx_sc::imports!();

#[multiversx_sc::contract]
pub trait EgldEsdtSwap: multiversx_sc_modules::pause::PauseModule {
    #[init]
    fn init(&self, wrapped_egld_token_id: TokenIdentifier) {
        self.wrapped_egld_token_id().set(&wrapped_egld_token_id);
    }

    // endpoints

    #[payable("EGLD")]
    #[endpoint(wrapEgld)]
    fn wrap_egld(&self) -> EsdtTokenPayment<Self::Api> {
        self.require_not_paused();

        let payment_amount = self.call_value().egld();
        require!(*payment_amount > 0u32, "Payment must be more than 0");

        let wrapped_egld_token_id = self.wrapped_egld_token_id().get();
        self.send()
            .esdt_local_mint(&wrapped_egld_token_id, 0, &payment_amount);

        self.tx()
            .to(ToCaller)
            .single_esdt(&wrapped_egld_token_id, 0, &payment_amount)
            .transfer();

        EsdtTokenPayment::new(wrapped_egld_token_id, 0, payment_amount.clone())
    }

    #[payable("*")]
    #[endpoint(unwrapEgld)]
    fn unwrap_egld(&self) {
        self.require_not_paused();

        let (payment_token, payment_amount) = self.call_value().single_fungible_esdt();
        let wrapped_egld_token_id = self.wrapped_egld_token_id().get();

        require!(*payment_token == wrapped_egld_token_id, "Wrong esdt token");
        require!(*payment_amount > 0u32, "Must pay more than 0 tokens!");
        require!(
            *payment_amount <= self.get_locked_egld_balance(),
            "Contract does not have enough funds"
        );

        self.send()
            .esdt_local_burn(&wrapped_egld_token_id, 0, &payment_amount);

        // 1 wrapped eGLD = 1 eGLD, so we pay back the same amount
        let caller = self.blockchain().get_caller();
        self.tx().to(&caller).egld(&*payment_amount).transfer();
    }

    #[view(getLockedEgldBalance)]
    #[title("lockedEgldBalance")]
    fn get_locked_egld_balance(&self) -> BigUint {
        self.blockchain()
            .get_sc_balance(&EgldOrEsdtTokenIdentifier::egld(), 0)
    }

    #[view(getWrappedEgldTokenId)]
    #[title("wrappedEgldTokenId")]
    #[storage_mapper("wrappedEgldTokenId")]
    fn wrapped_egld_token_id(&self) -> SingleValueMapper<TokenIdentifier>;
}