Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

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

2 changes: 1 addition & 1 deletion contract/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sweat_claim"
version = "1.0.1"
version = "1.0.2"
authors = ["Sweat Economy"]
edition = "2021"

Expand Down
19 changes: 15 additions & 4 deletions contract/src/claim/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,29 @@ impl ClaimApi for Contract {
};

let claim_period_refreshed_at = account_data.claim_period_refreshed_at;
if now_seconds() - claim_period_refreshed_at > self.claim_period {
ClaimAvailabilityView::Available
} else {
if claim_period_refreshed_at.is_within_period(now_seconds(), self.claim_period) {
ClaimAvailabilityView::Unavailable((claim_period_refreshed_at, self.claim_period))
} else {
let claimable_entries_count: u16 = account_data
.accruals
.iter()
.filter(|(datetime, _)| datetime.is_within_period(now_seconds(), self.burn_period))
.count()
.try_into()
.expect("To many claimable entries. Expected amount to fit into u16.");

ClaimAvailabilityView::Available(claimable_entries_count)
}
}

fn claim(&mut self) -> PromiseOrValue<ClaimResultView> {
let account_id = env::predecessor_account_id();

require!(
self.is_claim_available(account_id.clone()) == ClaimAvailabilityView::Available,
matches!(
self.is_claim_available(account_id.clone()),
ClaimAvailabilityView::Available(_)
),
"Claim is not available at the moment"
);

Expand Down
26 changes: 23 additions & 3 deletions contract/src/claim/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ fn test_check_claim_availability_when_user_has_tokens_and_claim_period_after_cla
context.set_block_timestamp_in_seconds(check_timestamp);

let alice_can_claim = contract.is_claim_available(accounts.alice.clone());
assert_eq!(alice_can_claim, ClaimAvailabilityView::Available);
assert_eq!(alice_can_claim, ClaimAvailabilityView::Available(0));
}

#[test]
Expand Down Expand Up @@ -103,7 +103,27 @@ fn test_check_claim_availability_when_user_has_tokens_and_claim_period_after_rec
assert_eq!(alice_balance, alice_new_balance);

let alice_can_claim = contract.is_claim_available(accounts.alice.clone());
assert_eq!(alice_can_claim, ClaimAvailabilityView::Available);
assert_eq!(alice_can_claim, ClaimAvailabilityView::Available(1));
}

#[test]
fn test_check_claim_availability_when_user_has_multiple_claim_records_and_claim_period_after_record_creation_is_passed()
{
let (mut context, mut contract, accounts) = Context::init_with_oracle();

let record_count: u16 = 5;
let alice_balance = 300_000;
context.switch_account(&accounts.oracle);

for i in 0..record_count {
contract.record_batch_for_hold(vec![(accounts.alice.clone(), U128(alice_balance))]);
context.set_block_timestamp_in_seconds(i as _);
}

context.set_block_timestamp_in_seconds(contract.claim_period as u64 + 100);

let alice_can_claim = contract.is_claim_available(accounts.alice.clone());
assert_eq!(alice_can_claim, ClaimAvailabilityView::Available(record_count));
}

#[test]
Expand Down Expand Up @@ -147,7 +167,7 @@ fn test_claim_when_user_has_tokens_and_current_time_matches_claim_period() {
assert_eq!(0, alice_new_balance);

let alice_can_claim = contract.is_claim_available(accounts.alice.clone());
assert_eq!(alice_can_claim, ClaimAvailabilityView::Available);
assert_eq!(alice_can_claim, ClaimAvailabilityView::Available(0));
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ async fn happy_flow() -> anyhow::Result<()> {
.await?;

let is_claim_available = context.sweat_claim().is_claim_available(alice.to_near()).await?;
assert_eq!(is_claim_available, ClaimAvailabilityView::Available);
assert_eq!(is_claim_available, ClaimAvailabilityView::Available(1));

context.sweat_claim().claim().with_user(&alice).await?;

Expand Down
20 changes: 9 additions & 11 deletions integration-tests/src/prepare.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
use async_trait::async_trait;
use integration_utils::{ misc::ToNear};
use claim_model::{
api::{AuthApiIntegration, ConfigApiIntegration, InitApiIntegration},
api::{AuthApiIntegration, ClaimContract, ConfigApiIntegration, InitApiIntegration},
Duration,
};
use integration_utils::misc::ToNear;
use near_sdk::json_types::U128;
use near_workspaces::Account;
use sweat_model::{StorageManagementIntegration, SweatApiIntegration, SweatContract};
use claim_model::api::ClaimContract;


const FT_CONTRACT: &str = "sweat";
const SWEAT_CLAIM: &str = "sweat_claim";
Expand Down Expand Up @@ -37,11 +35,15 @@ impl IntegrationContext for Context {
}

fn sweat_claim(&self) -> ClaimContract {
ClaimContract { contract: &self.contracts[SWEAT_CLAIM] }
ClaimContract {
contract: &self.contracts[SWEAT_CLAIM],
}
}

fn ft_contract(&self) -> SweatContract {
SweatContract { contract: &self.contracts[FT_CONTRACT] }
SweatContract {
contract: &self.contracts[FT_CONTRACT],
}
}
}

Expand All @@ -50,11 +52,7 @@ pub async fn prepare_contract() -> anyhow::Result<Context> {
let manager = context.manager().await?;
let alice = context.alice().await?;

context
.ft_contract()
.new(".u.sweat.testnet".to_string().into())

.await?;
context.ft_contract().new(".u.sweat.testnet".to_string().into()).await?;
context
.sweat_claim()
.init(context.ft_contract().contract.as_account().to_near())
Expand Down
1 change: 0 additions & 1 deletion model/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ pub struct ClaimContract<'a> {
pub contract: &'a near_workspaces::Contract,
}


/// An API for initializing smart contracts in the context of fungible token operations.
///
/// This API provides a method to initialize the smart contract, primarily for interactions
Expand Down
6 changes: 5 additions & 1 deletion model/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ pub type Duration = u32; // Period in seconds
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(crate = "near_sdk::serde", tag = "type", content = "data", rename_all = "snake_case")]
pub enum ClaimAvailabilityView {
Available,
/// Claim is available. Wrapped number is the amount of claimable entries.
Available(u16),
/// Claim is not available. Wrapped tuple is the timestamp the last claim
/// and the duration of the claim period.
Unavailable((UnixTimestamp, Duration)),
/// User is not registered in the contract.
Unregistered,
}

Expand Down
Binary file modified res/sweat_claim.wasm
Binary file not shown.