pub use crate::{
psp22,
psp22::utils::token_timelock,
traits::psp22::{
utils::token_timelock::*,
*,
},
};
use ink::{
env::CallFlags,
prelude::vec::Vec,
};
use openbrush::traits::{
AccountId,
Balance,
Storage,
Timestamp,
ZERO_ADDRESS,
};
pub use psp22::Internal as _;
pub use token_timelock::Internal as _;
pub const STORAGE_KEY: u32 = openbrush::storage_unique_key!(Data);
#[derive(Debug)]
#[openbrush::upgradeable_storage(STORAGE_KEY)]
pub struct Data {
token: AccountId,
beneficiary: AccountId,
release_time: Timestamp,
}
impl Default for Data {
fn default() -> Self {
Self {
token: ZERO_ADDRESS.into(),
beneficiary: ZERO_ADDRESS.into(),
release_time: Default::default(),
}
}
}
impl<T: Storage<Data>> PSP22TokenTimelock for T {
default fn token(&self) -> AccountId {
self.data().token
}
default fn beneficiary(&self) -> AccountId {
self.data().beneficiary
}
default fn release_time(&self) -> Timestamp {
self.data().release_time
}
default fn release(&mut self) -> Result<(), PSP22TokenTimelockError> {
if Self::env().block_timestamp() < self.data().release_time {
return Err(PSP22TokenTimelockError::CurrentTimeIsBeforeReleaseTime)
}
let amount = self._contract_balance();
if amount == 0 {
return Err(PSP22TokenTimelockError::NoTokensToRelease)
}
self._withdraw(amount)
}
}
pub trait Internal {
fn _withdraw(&mut self, amount: Balance) -> Result<(), PSP22TokenTimelockError>;
fn _contract_balance(&mut self) -> Balance;
fn _init(
&mut self,
token: AccountId,
beneficiary: AccountId,
release_time: Timestamp,
) -> Result<(), PSP22TokenTimelockError>;
fn _token(&mut self) -> &mut PSP22Ref;
}
impl<T: Storage<Data>> Internal for T {
default fn _withdraw(&mut self, amount: Balance) -> Result<(), PSP22TokenTimelockError> {
let beneficiary = self.beneficiary();
self._token()
.transfer_builder(beneficiary, amount, Vec::<u8>::new())
.call_flags(CallFlags::default().set_allow_reentry(true))
.try_invoke()
.unwrap()
.unwrap()?;
Ok(())
}
default fn _contract_balance(&mut self) -> Balance {
self._token().balance_of(Self::env().account_id())
}
default fn _init(
&mut self,
token: AccountId,
beneficiary: AccountId,
release_time: Timestamp,
) -> Result<(), PSP22TokenTimelockError> {
if release_time <= Self::env().block_timestamp() {
return Err(PSP22TokenTimelockError::ReleaseTimeIsBeforeCurrentTime)
}
self.data().token = token;
self.data().beneficiary = beneficiary;
self.data().release_time = release_time;
Ok(())
}
default fn _token(&mut self) -> &mut PSP22Ref {
&mut self.data().token
}
}