Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
065ab58
Remove deprecated specifications and documentation for delisted marke…
dacarva Dec 1, 2025
bc6ca29
Fix Core tropykus tests to work with Anvil forking Rootstock Mainnet.…
dacarva Dec 1, 2025
bb1d6a3
Refactor getAllMarketsInstances method in Comptroller to improve perf…
dacarva Dec 1, 2025
a718a49
Checkpoint. Fixing market tests
dacarva Dec 1, 2025
7656759
Enhance README with test execution instructions and update market tes…
dacarva Dec 1, 2025
2845a61
Refactor Unitroller tests to deploy fresh instances for improved reli…
dacarva Dec 1, 2025
e81d280
Update deprecation-config.js and related tests to reflect accurate ma…
dacarva Dec 1, 2025
e922b3d
Fix Quickstart validation test by adding error handling to ensure qui…
dacarva Dec 1, 2025
88c605d
Enhance README and test suite documentation with critical Anvil node …
dacarva Dec 1, 2025
2e2affc
Implement support for 6-decimal ERC20 tokens with 8-decimal price ora…
dacarva Dec 2, 2025
f8f77d8
Complete initial project setup by verifying existing structure and im…
dacarva Dec 2, 2025
1e5d8ce
Implement decimal detection for oracle adapters in PriceOracle. Add `…
dacarva Dec 2, 2025
7abb4c2
Enhance support for ERC20 tokens by integrating 6-decimal tokens with…
dacarva Dec 2, 2025
a021779
Decimals utils completed
dacarva Dec 2, 2025
0dbb21e
Integrate PriceOracle into the Tropykus package by importing it in `i…
dacarva Dec 2, 2025
e396157
Checkpoint. About to start priceoracle tasks
dacarva Dec 2, 2025
810012b
Update documentation to reflect changes in token integration, emphasi…
dacarva Dec 2, 2025
e7f09dc
Implement integration tests for 6-decimal token operations in `02-mar…
dacarva Dec 2, 2025
f65f4f8
Added mockPriceOracleAdapter for USDT0
dacarva Dec 3, 2025
a9456f8
Refactor balanceOfUnderlying and mint methods in CErc20 and Market cl…
dacarva Dec 3, 2025
40bcd91
Refactor balanceOfUnderlyingInWallet method in CErc20 to use async/aw…
dacarva Dec 3, 2025
b3500ad
Refactor borrowBalanceCurrent method in Market class to use async/awa…
dacarva Dec 3, 2025
dbf1636
Refactor CErc20 class to eliminate hardcoded factor and implement dyn…
dacarva Dec 3, 2025
4c196c9
Add redeem method to CErc20 class for token redemption with dynamic d…
dacarva Dec 3, 2025
d69e368
T021 completed. Token Transfers updated
dacarva Dec 3, 2025
71a3a17
Refactor Market and CErc20 classes to implement dynamic decimal handl…
dacarva Dec 3, 2025
f746b88
Update tests in 02-markets.spec.js to implement multi-market operatio…
dacarva Dec 3, 2025
929e5b5
Enhance Comptroller and Market classes to support dynamic decimal han…
dacarva Dec 3, 2025
e8c8691
Chekpoint. Fixing getTotalSupply
dacarva Dec 3, 2025
12c6bb8
Refactor getTotalSupplyInAllMarkets method in Comptroller to streamli…
dacarva Dec 3, 2025
54c4251
Fixing tests
dacarva Dec 3, 2025
35ee921
Refactor getTotalBorrowsInAllMarkets method in Comptroller to improve…
dacarva Dec 3, 2025
dc635a1
Enhance Market class to improve cToken calculation by implementing dy…
dacarva Dec 3, 2025
fc63d13
Refactor tests in 02-markets.spec.js to enable previously skipped tes…
dacarva Dec 3, 2025
6a882af
Update CHANGELOG for version 0.4.0, adding support for 6-decimal ERC2…
dacarva Dec 4, 2025
a76dacc
Deleted unnecesary files
dacarva Dec 4, 2025
30b2d87
Deleted Specs
dacarva Dec 4, 2025
422a121
Refactor project structure and update package names to align with new…
dacarva Jan 26, 2026
81a754f
Update README and .gitignore for Tropykus project. Remove deprecated …
dacarva Jan 26, 2026
5a50efa
Update version to 0.4.1-alpha in package.json and lerna.json. Enhance…
dacarva Jan 26, 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
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -494,4 +494,7 @@ packages/tropykus/.nyc_output/
packages/tropykus/.nyc_output/processinfo/index.json

.cursor/
.specify/
.specify/
.claude/

.DS_Store
826 changes: 413 additions & 413 deletions .pnp.cjs

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions .scripts/post-publish-checksums.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ PACKAGES=$( ls ./packages/ )
VERSION=$( node -p "require('./package').version" )
echo "\"module\",\"shasum\""
for PACKAGE in ${PACKAGES} ; do
PACKAGE_SHA=$( npm view @tropykus-finance/${PACKAGE}@${VERSION} dist.shasum )
echo "\"@tropykus-finance/${PACKAGE}@${VERSION}\",\"${PACKAGE_SHA}\""
PACKAGE_NAME=$( node -p "require('./packages/${PACKAGE}/package.json').name" )
PACKAGE_SHA=$( npm view ${PACKAGE_NAME}@${VERSION} dist.shasum )
echo "\"${PACKAGE_NAME}@${VERSION}\",\"${PACKAGE_SHA}\""
done
3 changes: 2 additions & 1 deletion .scripts/pre-publish-checksums.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ VERSION=$( node -p "require('./package').version" )
echo "\"module\",\"shasum\""
for PACKAGE in ${PACKAGES} ; do
cd ./packages/${PACKAGE}
PACKAGE_NAME=$( node -p "require('./package.json').name" )
PACKAGE_SHA=$( npm pack --dry-run 2>&1 >/dev/null | grep "shasum: " | awk '{print $NF}' )
echo "\"@tropykus-finance/${PACKAGE}@${VERSION}\",\"${PACKAGE_SHA}\""
echo "\"${PACKAGE_NAME}@${VERSION}\",\"${PACKAGE_SHA}\""
cd ../..
done
28 changes: 25 additions & 3 deletions .scripts/publish.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ set -e

PACKAGES=$( ls ./packages/ )
VERSION=$( node -p "require('./lerna.json').version" )

# Determine npm tag based on version type
# Prerelease versions (alpha, beta, rc) need a tag
if echo "${VERSION}" | grep -qE "-(alpha|beta|rc)"; then
# Extract the prerelease type (alpha, beta, rc)
# Use sed compatible with both BSD (macOS) and GNU sed
if echo "${VERSION}" | grep -qE "-alpha"; then
PRERELEASE_TYPE="alpha"
elif echo "${VERSION}" | grep -qE "-beta"; then
PRERELEASE_TYPE="beta"
elif echo "${VERSION}" | grep -qE "-rc"; then
PRERELEASE_TYPE="rc"
else
PRERELEASE_TYPE="next"
fi
NPM_TAG="${PRERELEASE_TYPE}"
else
# Stable versions use "latest" tag (default)
NPM_TAG="latest"
fi

echo "\"module\",\"shasum_local\",\"shasum_remote\""
for PACKAGE in ${PACKAGES} ; do
cd ./packages/${PACKAGE}
Expand All @@ -13,10 +34,11 @@ for PACKAGE in ${PACKAGES} ; do
echo "${PACKAGE} - expected version to be ${VERSION}, but found ${PACKAGE_VERSION}"
exit 1
fi
PACKAGE_NAME=$( node -p "require('./package.json').name" )
PACKAGE_SHA_LOCAL=$( npm pack --dry-run 2>&1 >/dev/null | grep "shasum: " | awk '{print $NF}' )
npm publish --access public
PACKAGE_SHA_REMOTE=$( npm view @tropykus-finance/${PACKAGE}@${VERSION} dist.shasum )
echo "\"@tropykus-finance/${PACKAGE}@${VERSION}\",\"${PACKAGE_SHA_LOCAL}\",\"${PACKAGE_SHA_REMOTE}\""
npm publish --access public --tag "${NPM_TAG}"
PACKAGE_SHA_REMOTE=$( npm view ${PACKAGE_NAME}@${VERSION} dist.shasum )
echo "\"${PACKAGE_NAME}@${VERSION}\",\"${PACKAGE_SHA_LOCAL}\",\"${PACKAGE_SHA_REMOTE}\""
if [ "${PACKAGE_SHA_LOCAL}" != "${PACKAGE_SHA_REMOTE}" ] ; then
echo "${PACKAGE} - local shasum is ${PACKAGE_SHA_LOCAL}, but published shasum is ${PACKAGE_SHA_REMOTE}"
exit 1
Expand Down
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,37 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.4.0] - 2025-12-04

### Added

- Support for 6-decimal ERC20 tokens (USDT0) with dynamic decimal detection
- `detectOracleDecimals` method in PriceOracle class for automatic oracle decimal detection
- Decimal utility functions in `utils/decimals.js` for token and oracle decimal handling
- Comprehensive integration tests for 6-decimal token operations (deposit, borrow, repay, redeem)
- Mock price oracle adapter for USDT0 testing

### Changed

- Refactored Market and CErc20 classes to use dynamic decimal handling instead of hardcoded factors
- Updated `balanceOfUnderlying`, `mint`, `borrow`, `repayBorrow`, and `redeem` methods to support variable token decimals
- Enhanced `getAccountLiquidity`, `getTotalSupplyInAllMarkets`, and `getTotalBorrowsInAllMarkets` in Comptroller for accurate calculations with mixed decimal tokens
- Migrated test suite to use Anvil for forking RSK Mainnet network
- Updated test assertions to use `closeTo` for better precision in liquidity and borrowing calculations
- Improved USD value calculations to handle mixed decimal scenarios (6-decimal tokens with 18-decimal and 30-decimal price oracles)

### Documentation

- Updated README.md to clarify USDT0 (6-decimal) vs deprecated kUSDT (18-decimal rUSDT) distinction
- Enhanced documentation on decimal handling for new token integrations
- Added test execution instructions with Anvil node requirements

### Notes

- **Backward Compatibility**: All existing 18-decimal token operations remain fully functional. The changes are backward compatible.
- **Decimal Detection**: Token and oracle decimals are now automatically detected and cached for improved performance.
- **Test Infrastructure**: Tests now require Anvil node to be running with RSK Mainnet fork. Anvil must be restarted between full test suite runs to ensure clean state.

## [0.3.0] - 2025-01-XX

### Deprecated
Expand Down
81 changes: 67 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,45 @@

The Tropykus Protocol is developed using RSK smart contracts for supplying or borrowing assets. Through the cToken contracts, accounts on the blockchain supply capital (RBTC or ERC-20 tokens) to receive kTokens. Accounts may also do the reverse, and borrow assets from the protocol, using other assets as collateral.

The Tropykus cToken contracts (CRBTC, CERC20Immutable and CRDOC) track these balances, and algorithmically set interest rates for borrowers. This process is described in greater detail, in the [Tropykus Whitepaper](https://firebasestorage.googleapis.com/v0/b/tropycofinance.appspot.com/o/Tropykus_Protocol%20V4.pdf?alt=media&token=d2b0cb1e-4163-432f-8b17-38df7393baff).
The Tropykus cToken contracts (CRBTC and CERC20Immutable) track these balances, and algorithmically set interest rates for borrowers. This process is described in greater detail, in the [Tropykus Whitepaper](https://firebasestorage.googleapis.com/v0/b/tropycofinance.appspot.com/o/Tropykus_Protocol%20V4.pdf?alt=media&token=d2b0cb1e-4163-432f-8b17-38df7393baff).

# Tropykusjs

[@tropykus-finance/tropykus](https://www.npmjs.com/package/@tropykus-finance/tropykus) npm package enables developers to interact with a deployed instance of Tropykus smart contracts by simply importing it as a dependency.
[@tropykus/tropykuslibs](https://www.npmjs.com/package/@tropykus/tropykuslibs) npm package enables developers to interact with a deployed instance of Tropykus smart contracts by simply importing it as a dependency.

## Install tropykus
``` bash
$ npm init
$ npm install @babel/runtime
$ npm install @tropykus-finance/tropykus
$ npm install @tropykus/tropykuslibs
```

## Running Tests

Before running the test suite, you need to start a local Anvil node that forks the RSK Mainnet network:

```bash
anvil --fork-url https://public-node.rsk.co --chain-id 30 --port 8545
```

This command:
- Forks the RSK Mainnet network (`https://public-node.rsk.co`)
- Sets the chain ID to 30 (RSK Mainnet)
- Runs the local node on port 8545 (default)

Once Anvil is running, you can run the tests in a separate terminal:

```bash
yarn test
```

> **Note**: Make sure Anvil is running before executing tests, as the test suite requires a local blockchain node to be available at `http://127.0.0.1:8545`.

> **⚠️ Important**: Before running the full test suite (`yarn test`), you **MUST** restart the Anvil node to ensure a clean state. This prevents nonce conflicts, state pollution, and transaction errors from previous test runs. To restart Anvil, stop the current process and start a fresh instance with the same command above.

Comment on lines +20 to +42
Copy link

@coderabbitai coderabbitai bot Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Test instructions and USDT0 clarifications read well; just fix the markdownlint blockquote warning.

The new “Running Tests” section and the Anvil notes are clear and match the new Anvil-based test setup, and the USDT0 vs kUSDT decimal explanation later in the README is very helpful.

markdownlint (MD028) is flagging a “Blank line inside blockquote” around the Anvil notes (lines 39–41). There appears to be an empty blockquote line between the two quoted notes. You can fix this by either:

  • Removing the empty quoted line entirely, or
  • Making sure each blockquote paragraph is consecutive without a blank > line in between.

Content-wise this section is good; this is just to keep markdownlint happy.

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

40-40: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 Prompt for AI Agents
In README.md around lines 20 to 42, markdownlint MD028 flags a blank line inside
a blockquote in the Anvil notes; remove the empty quoted line or merge the two
blockquote paragraphs so there is no `>`-prefixed blank line between them
(ensure consecutive blockquote lines or collapse into a single blockquote
paragraph) to satisfy markdownlint.

Copy link

@NataliaMunozC NataliaMunozC Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the blank line

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NataliaMunozC, here's the fix for the markdownlint warning. You need to remove the empty line between the two blockquote notes.

Current code (with the blank line issue):

> **Note**: Make sure Anvil is running before executing tests, as the test suite requires a local blockchain node to be available at `http://127.0.0.1:8545`.

> **⚠️ Important**: Before running the full test suite (`yarn test`), you **MUST** restart the Anvil node to ensure a clean state. This prevents nonce conflicts, state pollution, and transaction errors from previous test runs. To restart Anvil, stop the current process and start a fresh instance with the same command above.

Fixed version (remove the empty line between blockquotes):

> **Note**: Make sure Anvil is running before executing tests, as the test suite requires a local blockchain node to be available at `http://127.0.0.1:8545`.
> **⚠️ Important**: Before running the full test suite (`yarn test`), you **MUST** restart the Anvil node to ensure a clean state. This prevents nonce conflicts, state pollution, and transaction errors from previous test runs. To restart Anvil, stop the current process and start a fresh instance with the same command above.

Alternatively, you could merge them into a single blockquote with a blank line inside (but this is less clear):

> **Note**: Make sure Anvil is running before executing tests, as the test suite requires a local blockchain node to be available at `http://127.0.0.1:8545`.
>
> **⚠️ Important**: Before running the full test suite (`yarn test`), you **MUST** restart the Anvil node to ensure a clean state. This prevents nonce conflicts, state pollution, and transaction errors from previous test runs. To restart Anvil, stop the current process and start a fresh instance with the same command above.

I recommend the first approach (consecutive blockquotes with no empty line between them) as it's cleaner and satisfies markdownlint.

## Use tropykus in your app
```javascript
const Tropykus = require('@tropykus-finance/tropykus');
const Tropykus = require('@tropykus/tropykuslibs');

const tropykus = new Tropykus('https://public-node.testnet.rsk.co', 400000);

Expand Down Expand Up @@ -90,19 +113,51 @@ args = {
const crbtc = await tropykus.addMarket('CRBTC', true, crbtcMarketAddress);
```

**For cTokens (cDOC, cRIF, cUSDT):**
**For cTokens (cDOC, CBPRO, cUSDRIF):**
```javascript
const cdoc = await tropykus.addMarket('CErc20Immutable', true, cdocAddress, docAddress);
```

> **⚠️ Deprecation Notice**: cRIF and cUSDT markets are deprecated (delisted from protocol). Please use supported markets (cDOC, cRBPRO, cRBTC, cUSDRF) instead.

**For cRDOC:**
> **Note**: USDT0 refers to the standard 6-decimal USDT token on Rootstock. The deprecated kUSDT market used rUSDT, an 18-decimal wrapped version. New integrations should use USDT0 with 6 decimals for proper decimal handling and compatibility with current standards.

**For USDT0 (6-Decimal Token):**

USDT0 is a 6-decimal token that uses a 30-decimal price oracle adapter. The library automatically detects both the token decimals (6) and oracle decimals (30) for accurate USD value calculations.

```javascript
const crdoc = await tropykus.addMarket('CRDOC', true, rcdocAddress, rdocAddress);
// Add USDT0 market using CErc20Immutable artifact
const cusdt0 = await tropykus.addMarket('CErc20Immutable', true, usdt0MarketAddress, usdt0TokenAddress);

// Mint 1.5 USDT0 - automatically converts to 1500000 (1.5 × 10^6) internally
await cusdt0.mint(tropykus.account, 1.5);

// Check balance - returns human-readable values
const balance = await cusdt0.balanceOfUnderlying(tropykus.account);
// Returns: { value: 1.5, usd: 1.5 } (assuming $1 USDT price)
console.log('Balance:', balance.value, 'USDT0');
console.log('USD Value:', balance.usd, 'USD');

// Borrow 0.5 USDT0 - automatically converts to 500000 (0.5 × 10^6) internally
await cusdt0.borrow(tropykus.account, 0.5);

// Check borrow balance
const borrowBalance = await cusdt0.borrowBalanceCurrent(tropykus.account);
console.log('Borrowed:', borrowBalance.value, 'USDT0');

// Repay borrowed amount
await cusdt0.repayBorrow(tropykus.account, 0.5);

// Redeem deposited tokens
await cusdt0.redeem(tropykus.account, 1.0);
```

> **⚠️ Deprecation Notice**: cRDOC market is deprecated (never listed). Please use supported markets instead.
> **Note**: The library automatically detects:
> - **Token decimals**: 6 for USDT0 (via `getTokenDecimals()`)
> - **Oracle decimals**: 30 for USDT price oracle adapter (via `detectOracleDecimals()`)
>
> All decimal conversions are handled automatically. You can work with human-readable values (e.g., `1.5 USDT0`) and the library converts them to the correct contract format internally.

Then mint function can be called using the assigned tropykus account to sign the transaction

Expand Down Expand Up @@ -167,7 +222,7 @@ await crbtc.redeem(account, value);
### Example

```javascript=
const cdoc = await tropykus.addMarket('CDOC', true, rcdocAddress, rdocAddress);
const cdoc = await tropykus.addMarket('CErc20Immutable', true, cdocAddress, docAddress);

// It's necesary have founds in the market to be able to redeem
await cdoc.mint(tropykus.account, depositValue);
Expand Down Expand Up @@ -230,17 +285,15 @@ The third parameter is a flag that indicates the method that must pay all the de
| **kBPRO** | 0x844a99Ba756539Aee698ce2915d678bA0FeE4d9d | 0x405062731d8656af5950ef952be9fa110878036b |
| **kRBTC** | 0x636b2c156d09cee9516f9afec7a4605e1f43dec1 | 0x0aeadb9d4c6a80462a47e87e76e487fa8b9a37d7 |
| **kUSDRF** | 0xfbee4444493194468df1de7450a37d840eb8b555 | 0xDdf3CE45fcf080DF61ee61dac5Ddefef7ED4F46C |
| **kUST0** | 0xF66513302Ad4F64a7C00888c1174d18ee22Ed5f2 | N/A |

## Deprecated Markets and Functions

> **⚠️ Deprecated Markets Notice**: The following markets are deprecated and should not be used in new projects: kSAT/cSAT (delisted from protocol), kRDOC/cRDOC (never listed), kRIF (delisted from protocol), and kUSDT (delisted from protocol). These markets remain functional for backward compatibility but are no longer actively supported. Please use supported markets (kDOC, kRBPRO, kRBTC, kUSDRF) instead.
> **⚠️ Deprecated Markets Notice**: The following markets are deprecated and should not be used in new projects: kSAT/cSAT (delisted from protocol), kRDOC/cRDOC (never listed), kRIF (delisted from protocol), and kUSDT (delisted from protocol - used 18-decimal rUSDT, not the standard 6-decimal USDT0). These markets remain functional for backward compatibility but are no longer actively supported. Please use supported markets (kDOC, kRBPRO, kRBTC, kUSDRF) instead.

| Contract | Rootstock Testnet | Rootstock Mainnet |
| -------- | ----------------- | ----------------- |
| **kSAT ⚠️ DEPRECATED** | 0x13f3a4013e77a65b0cd941b8b0e1687e8f3a0e1d | 0xd2ec53e8dd00d204d3d9313af5474eb9f5188ef6 |
| **kUSDT ⚠️ DEPRECATED** | 0x5539d6d48a2147cb824c5c45baaa01e7e1a2694f | 0xedaefc6b596ed38d712100976969975a37c84464 |
| **kRIF ⚠️ DEPRECATED** | 0x23b60e2193057b4b2823973b7478489a076de84f | 0x3134b7fbfca5db217eca523eab1941452cf35163 |
| **kRDOC ⚠️ DEPRECATED** | 0x0981eb51a91e6f89063c963438cadf16c2e44962 | - |



| **kRDOC ⚠️ DEPRECATED** | 0x0981eb51a91e6f89063c963438cadf16c2e44962 | - |
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.2.17",
"version": "0.4.1-alpha",
"command": {
"init": {
"exact": true
Expand Down
Loading