Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
6455bf2
feat: introduce Features type describing set of features for an Accou…
vasyafromrussia Sep 25, 2025
c0884bb
feat: introduce Booster entity (#145)
vasyafromrussia Sep 26, 2025
1b6973a
feat: add boosted score to Account (#146)
vasyafromrussia Oct 7, 2025
a3e59be
feat: add tiered score based product (#147)
vasyafromrussia Oct 9, 2025
84f4ef6
fix: AccountView mapping
vasyafromrussia Oct 10, 2025
c0f7fa1
feat: add features to AccountView (#148)
vasyafromrussia Oct 10, 2025
d5c2126
feat: create account on settings update (#149)
vasyafromrussia Oct 13, 2025
f53352c
feat: emit event when a booster is applied (#150)
vasyafromrussia Oct 13, 2025
0264cd8
chore: fix typos
vasyafromrussia Oct 13, 2025
4c95c57
chore: fix lint
vasyafromrussia Oct 13, 2025
a2c33fd
fix: fix integration tests
vasyafromrussia Oct 13, 2025
0da48d7
chore: clean dependencies
vasyafromrussia Oct 14, 2025
ddc6b67
fix: mutants and dependencies
vasyafromrussia Oct 14, 2025
75e5f8e
feat: add integration tests (#151)
vasyafromrussia Oct 20, 2025
9f40e8e
chore: clean outdated code
vasyafromrussia Nov 13, 2025
d7fea2e
feat: add timezone to Account view
vasyafromrussia Nov 17, 2025
2219a7e
fix: valid booster value in Score view
vasyafromrussia Nov 17, 2025
8b1f916
fix: tests and lint
vasyafromrussia Nov 24, 2025
a211397
chore: update test workflow
vasyafromrussia Nov 24, 2025
80cab7b
chore: better error message
vasyafromrussia Nov 24, 2025
a468690
fix: proper score cap in interest calculator
vasyafromrussia Nov 26, 2025
905bbcb
fix: apply current score based apy to new deposit
vasyafromrussia Nov 27, 2025
44faa22
fix: build on ci
vasyafromrussia Nov 28, 2025
474c56b
fix: mutants
vasyafromrussia Nov 28, 2025
95ea5fa
fix: fix time traveling in tests
vasyafromrussia Dec 2, 2025
a9ab53a
feat: dynamic yield (#152)
vasyafromrussia Dec 24, 2025
4afa475
fix: typos
vasyafromrussia Dec 24, 2025
d8627cc
fix: integration tests
vasyafromrussia Jan 12, 2026
467a112
test: cover mutant fails
vasyafromrussia Jan 12, 2026
607f3f6
fix: overflow in compound score calculation
vasyafromrussia Jan 13, 2026
033f100
chore: clean tests
vasyafromrussia Jan 13, 2026
3f60fa0
fix: don't apply too old boosters
vasyafromrussia Jan 13, 2026
f9c6d26
refactor: extract UDecimal type to primitives package
vasyafromrussia Jan 13, 2026
8abef8c
fix: mul overflow in interest calculation
vasyafromrussia Jan 13, 2026
c77e985
test: fix mutants
vasyafromrussia Jan 14, 2026
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
6 changes: 3 additions & 3 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ debug = false
panic = "abort"
overflow-checks = true

[profile.test]
inherits = "release"
lto = false
# [profile.test]
# lto = false
# debug = true
7 changes: 7 additions & 0 deletions .cargo/mutants.toml
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
exclude_globs = ["integration-tests/**"]

# Score field in AccountCompanion rollback cannot be effectively tested because:
# 1. settle_interest() modifies the score BEFORE rollback is captured
# 2. The rollback value equals the current value (post-settle_interest)
# 3. Deleting the field has no observable effect on test outcomes
# See: contract/src/feature/claim/api.rs:92
exclude_re = ["delete field score from struct AccountCompanion expression"]
19 changes: 14 additions & 5 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ name: Push

on:
push:
branches: [ main* ]
branches: [main*]

env:
CARGO_TERM_COLOR: always

jobs:

typos:
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -37,7 +36,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Install tools
run: cargo install --locked cargo-near
run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/cargo-near/releases/download/cargo-near-v0.17.0/cargo-near-installer.sh | sh

- name: Checkout
uses: actions/checkout@v4
Expand Down Expand Up @@ -69,7 +68,7 @@ jobs:
uses: actions/checkout@v4

- name: Install cargo-near CLI
run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/cargo-near/releases/download/cargo-near-v0.15.0/cargo-near-installer.sh | sh
run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/cargo-near/releases/download/cargo-near-v0.17.0/cargo-near-installer.sh | sh

- name: Integration tests
run: make integration
Expand Down Expand Up @@ -102,7 +101,17 @@ jobs:
path: measured.txt

push:
needs: [ build, typos, unused-dependencies, lint, unit-tests, integration-tests, measure, mutation-tests ]
needs:
[
build,
typos,
unused-dependencies,
lint,
unit-tests,
integration-tests,
measure,
mutation-tests,
]
runs-on: ubuntu-latest
steps:
- name: Checkout
Expand Down
11 changes: 5 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@ name: Test

on:
pull_request:
branches: [ main*, dev*, release* ]
branches: [main*, dev*, release*]

env:
CARGO_TERM_COLOR: always

jobs:

typos:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: crate-ci/typos@v1.21.0
- uses: crate-ci/typos@v1.39.2

unused-dependencies:
runs-on: ubuntu-latest
Expand All @@ -39,8 +38,8 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Install cargo-near CLI
run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/cargo-near/releases/download/cargo-near-v0.15.0/cargo-near-installer.sh | sh
- name: Install tools
run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/cargo-near/releases/download/cargo-near-v0.17.0/cargo-near-installer.sh | sh

- name: Build
run: make build
Expand All @@ -60,7 +59,7 @@ jobs:
uses: actions/checkout@v4

- name: Install cargo-near CLI
run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/cargo-near/releases/download/cargo-near-v0.15.0/cargo-near-installer.sh | sh
run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/cargo-near/releases/download/cargo-near-v0.17.0/cargo-near-installer.sh | sh

- name: Integration tests
run: make integration
Expand Down
33 changes: 33 additions & 0 deletions Cargo.lock

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

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
resolver = "2"

default-members = ["contract"]
members = ["model", "contract", "integration-tests"]
members = ["primitives", "model", "contract", "integration-tests"]

[workspace.dependencies]
anyhow = "1.0.75"
Expand All @@ -22,10 +22,12 @@ crypto-hash = "0.3.4"
itertools = "0.13"
tokio = { version = "1.37", features = ["full"] }
dirs = "5.0"
strum = { version = "0.27", features = ["derive"] }

nitka = "0.4.0"
nitka-proc = "0.4.0"

sweat-jar-primitives = { path = "primitives" }
sweat-jar-model = { path = "model" }
sweat-model = { git = "https://github.com/sweatco/sweat-near", rev = "537ef7d0aa3bf58d87b77a1c9660b2d0299b6c00" }

Expand Down
4 changes: 3 additions & 1 deletion contract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ container_build_command = [
[features]
default = ["release"]
release = ["sweat-jar-model/release-api"]
integration-methods = ["sweat-jar-model/integration-methods"]
integration-test = [
"sweat-jar-model/release-api",
"sweat-jar-model/integration-methods",
"integration-methods",
]
integration-api = ["sweat-jar-model/integration-api"]

Expand All @@ -37,6 +38,7 @@ near-self-update-proc = { workspace = true }
near-contract-standards = { workspace = true }

sweat-jar-model = { workspace = true }
sweat-jar-primitives = { workspace = true }

[dev-dependencies]
fake = { workspace = true }
Expand Down
40 changes: 38 additions & 2 deletions contract/src/common/api.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#![cfg(feature = "integration-test")]

use near_sdk::{env, near, AccountId, Timestamp};
use sweat_jar_model::{api::IntegrationTestMethods, data::product::ProductId};
use near_sdk::{env, json_types::U128, near, AccountId, Timestamp};
use sweat_jar_model::{
api::IntegrationTestMethods,
data::product::{ProductAssertions, ProductId, Terms},
Timezone,
};

use crate::{Contract, ContractExt};

Expand All @@ -21,4 +25,36 @@ impl IntegrationTestMethods for Contract {
account.deposit(&product_id, principal, (now + i as u64).into());
}
}

fn set_time_scale(&mut self, time_scale: f64) {
self.assert_manager();
self.time_scale = time_scale;
sweat_jar_model::set_global_time_scale(time_scale);
}

fn seed_accounts(
&mut self,
product_id: ProductId,
accounts: Vec<(AccountId, U128, Timezone)>,
deposit_timestamp_ms: u64,
) {
self.assert_manager();
let product = self.get_product(&product_id);
product.assert_enabled();

for (account_id, principal, timezone) in accounts {
let principal_value = principal.0;
product.assert_cap(principal_value);

let account = self.get_or_create_account_mut(&account_id);
if matches!(product.terms, Terms::ScoreBased(_) | Terms::TieredScoreBased(_)) {
account.timezone = timezone;
account.score = Default::default();
}
account.jars.remove(&product_id);
account.deposit(&product_id, principal_value, Some(deposit_timestamp_ms));

self.update_jar_cache(&account_id, &product_id);
}
}
}
7 changes: 7 additions & 0 deletions contract/src/common/assertions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ impl Contract {
"Can migrate data only from previous version"
);
}

pub(crate) fn assert_timezone_is_set(&self, account_id: &AccountId) {
assert!(
self.get_account(account_id).is_timezone_set(),
"Timezone is not set for account '{account_id}'"
);
}
}

pub(crate) fn assert_gas<Message: Display>(gas_needed: u64, error: impl FnOnce() -> Message) {
Expand Down
19 changes: 17 additions & 2 deletions contract/src/common/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use near_sdk::{
log, near, serde_json, AccountId,
};
use sweat_jar_model::{
data::product::{Product, ProductId},
data::{
account::features::Feature,
product::{Product, ProductId},
},
Local, Score, Timestamp, TokenAmount, UTC,
};

Expand All @@ -29,6 +32,9 @@ pub enum EventKind {
OldScoreWarning((Score, Local)),
JarsMerge(AccountId),
MigrateProducts(Vec<ProductId>),
SetFeatureEnabled(AccountId, Feature, bool),
BatchSetFeatureEnabled(Vec<AccountId>, Feature, bool),
ApplyBooster(ApplyBoosterData),
}

#[derive(Debug)]
Expand Down Expand Up @@ -170,7 +176,16 @@ pub struct ChangeProductPublicKeyData {
#[near(serializers=[json])]
pub struct ScoreData {
pub account_id: AccountId,
pub score: Vec<(Score, UTC)>,
pub score: Vec<(Score, Local)>,
}

#[derive(Debug, Clone)]
#[near(serializers=[json])]
pub struct ApplyBoosterData {
pub applied: Vec<AccountId>,
pub rejected: Vec<AccountId>,
pub timestamp: UTC,
pub score: Score,
}

impl From<EventKind> for SweatJarEvent {
Expand Down
Loading