You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
3.4 KiB
112 lines
3.4 KiB
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!!)); |
|
} |
|
} |