|
|
|
import "constants";
|
|
|
|
import "messages";
|
|
|
|
|
|
|
|
fun stakingDepositMessage(value: Int, pool: Address): SendParameters {
|
|
|
|
return SendParameters{
|
|
|
|
to: pool,
|
|
|
|
value: value,
|
|
|
|
body: beginCell().storeUint(0x7bcd1fef, 32)/*.storeSlice("Deposit".asSlice())*/.endCell()
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
fun stakingWithdrawMessage(value: Int, pool: Address): SendParameters {
|
|
|
|
return SendParameters{
|
|
|
|
to: pool,
|
|
|
|
value: ton("0.05"),
|
|
|
|
body: beginCell().storeUint(3665837821, 32).storeCoins(value).endCell()
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
struct WithdrawalRequests {
|
|
|
|
addresses: map[Int]Address;
|
|
|
|
amounts: map[Int]Int;
|
|
|
|
n_requests: Int = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
fun withdrawalSum(requests: WithdrawalRequests): Int {
|
|
|
|
let sum: Int = 0;
|
|
|
|
let i: Int = 0;
|
|
|
|
while(i < requests.n_requests) {
|
|
|
|
sum = sum + requests.amounts.get(i)!!;
|
|
|
|
i = i + 1;
|
|
|
|
}
|
|
|
|
return sum;
|
|
|
|
}
|
|
|
|
|
|
|
|
trait StakingTrait {
|
|
|
|
staking_pool: Address?;
|
|
|
|
withdrawal_requests: WithdrawalRequests;
|
|
|
|
owner: Address;
|
|
|
|
in_the_pool: Int = 0;
|
|
|
|
|
|
|
|
fun sendStake() {
|
|
|
|
if(self.staking_pool == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let value: Int = myBalance() - tonb_floor - staking_gas;
|
|
|
|
if(value < ton("0.05")) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
self.in_the_pool = self.in_the_pool + value;
|
|
|
|
send(stakingDepositMessage(value, self.staking_pool!!));
|
|
|
|
}
|
|
|
|
|
|
|
|
fun sendWithdrawal() {
|
|
|
|
if(self.staking_pool == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let value: Int = withdrawalSum(self.withdrawal_requests);
|
|
|
|
send(stakingWithdrawMessage(value, self.staking_pool!!));
|
|
|
|
}
|
|
|
|
|
|
|
|
receive("Withdraw completed") {
|
|
|
|
let i: Int = 0;
|
|
|
|
while(i < self.withdrawal_requests.n_requests) {
|
|
|
|
let addr: Address = self.withdrawal_requests.addresses.get(i)!!;
|
|
|
|
send(SendParameters{
|
|
|
|
to: addr,
|
|
|
|
value: ton("0.08"),
|
|
|
|
bounce: false,
|
|
|
|
body: TokenBurn{
|
|
|
|
amount: self.withdrawal_requests.amounts.get(i)!!,
|
|
|
|
queryId: 0,
|
|
|
|
responseAddress: myAddress(),
|
|
|
|
owner: addr
|
|
|
|
}.toCell()
|
|
|
|
});
|
|
|
|
i = i + 1;
|
|
|
|
}
|
|
|
|
let ctx: Context = context();
|
|
|
|
let val: Int = ctx.value;
|
|
|
|
self.in_the_pool = self.in_the_pool - val;
|
|
|
|
if (self.in_the_pool < 0) {
|
|
|
|
let value: Int = -self.in_the_pool;
|
|
|
|
send(SendParameters{
|
|
|
|
to: self.owner,
|
|
|
|
value: value,
|
|
|
|
body: Unstake{amount: value}.toCell()
|
|
|
|
});
|
|
|
|
self.in_the_pool = 0;
|
|
|
|
}
|
|
|
|
self.withdrawal_requests = WithdrawalRequests{
|
|
|
|
addresses: emptyMap(),
|
|
|
|
amounts: emptyMap()
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
receive(msg: Unstake) {
|
|
|
|
if(self.staking_pool == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let ctx: Context = context();
|
|
|
|
require(ctx.sender == self.owner, "Only the owner can trigger un-staking");
|
|
|
|
send(stakingWithdrawMessage(msg.amount /* 0 to unstake all */, self.staking_pool!!));
|
|
|
|
}
|
|
|
|
|
|
|
|
fun requestWithdrawal(address: Address, value: Int) {
|
|
|
|
self.withdrawal_requests.addresses.set(self.withdrawal_requests.n_requests, address);
|
|
|
|
self.withdrawal_requests.amounts.set(self.withdrawal_requests.n_requests, value);
|
|
|
|
self.withdrawal_requests.n_requests = self.withdrawal_requests.n_requests + 1;
|
|
|
|
send(stakingWithdrawMessage(value, self.staking_pool!!));
|
|
|
|
}
|
|
|
|
}
|