Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
9aab8f9
docs: review base CW20
Jun 25, 2025
46c9600
docs: add more info on compliance
Jun 25, 2025
53c370f
chore: make contract dependency more obvious
Jun 25, 2025
11cc035
docs: add owner roles used
Jun 25, 2025
bc75915
docs: add initial review of codebase
Jun 25, 2025
a47b5df
chore: update gitignore
jhelison Jun 30, 2025
933679f
refactor: fix typo on claim management
jhelison Jun 30, 2025
d9ade8e
chore: add contract manipulation scripts
jhelison Jun 30, 2025
f73c3bb
refactor: move configs to a config file
Jul 1, 2025
721e6cf
docs: add else to not duplicate messages
Jul 1, 2025
eb2c84a
docs: improve legibility
Jul 1, 2025
7e7bde4
feat: add initial user setup
Jul 1, 2025
f1c66d3
docs: add more docs to review
Jul 1, 2025
97b0e41
chore: move kiichaind to a variable
Jul 2, 2025
5382928
fix: correct typo
Jul 2, 2025
5c50407
fix: correct typo
Jul 2, 2025
82c26db
feat: add user setup
Jul 2, 2025
8d5c3cf
fix: make script chmod
Jul 2, 2025
44ab430
feat: full user setup flow
Jul 2, 2025
5de633d
fix: add missing identity to trusted user
Jul 2, 2025
1b6da86
docs: add small comment on usage
Jul 2, 2025
c4012d5
feat: add missing compliance setup
Jul 2, 2025
13f0f78
docs: add a new incomplete issue
Jul 2, 2025
9f19681
chore: clean up some unused variables
Jul 2, 2025
9e06e83
feat: add default case
Jul 2, 2025
36046cb
fix: add missing compliance manager setup
Jul 2, 2025
3053a09
fix: chmod script
Jul 2, 2025
e0d01a8
docs: add details to compliance registry limitations
Jul 2, 2025
172162c
feat: add balance check script
Jul 2, 2025
610231e
chore: remove excessive spaces
Jul 2, 2025
2fcc1ad
chore: remove excessive spaces
Jul 2, 2025
96b395d
fix: incorrect claim restriction
Jul 2, 2025
bd8b548
feat: add transfer script
Jul 2, 2025
777f6f7
fix: correct typo on transfer
Jul 2, 2025
c9ec5ff
fix: correct fmt
Jul 2, 2025
eb005d0
fix: use correct main call
Jul 2, 2025
4d68c1f
fix: use correct main check
Jul 2, 2025
6a48241
feat: handle contract exceptions
Jul 2, 2025
6fd88df
chore: fix clippy warnings
Jul 2, 2025
6020f66
chore: fix fmt
Jul 2, 2025
96bc5bc
chore: fix clippy warnings
Jul 2, 2025
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: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,9 @@
# IDEs
*.iml
.idea

# Artifacts from builds
artifacts/

# Python artifacts
__pycache__/
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ Extends the CW20 standard with T-REX functionalities and implements permissioned

#### Storage
- `token_info`: TokenInfo
- Name, symbol, decimals, supply and minter(opt)
- Minter has an addr and can have a cap
- `balances`: Map<Addr, Uint128>
- `allowances`: Map<(Addr, Addr), AllowanceInfo>
- uint with an expiration date
- `identity_registry`: Addr
- `compliance`: Addr

Expand All @@ -28,6 +31,13 @@ Extends the CW20 standard with T-REX functionalities and implements permissioned
- Description: Transfers tokens on behalf of the owner if the recipient is verified and compliant.
- Interaction: Similar to `transfer`, but checks allowances first.

- `send(contract: Addr, amount: Uint128, msg: Binary) -> Result<Response>`
- Msg is weird `Binary::from(r#"{"some":123}"#.as_bytes());`
- `burn(amount: Uint128) -> Result<Response>`
- `mint(contract: Addr, amount: Uint128) -> Result<Response>`
- Increase/Decrease Allowance
- Can also change expiration

#### Query
- `balance(address: Addr) -> BalanceResponse`
- `token_info() -> TokenInfoResponse`
Expand Down Expand Up @@ -77,7 +87,7 @@ Stores the mapping of wallet addresses to identity contracts.

### 4. Trusted Issuers Registry

Manages the list of trusted claim issuers.
Manages the list of trusted claim issuers. OwnerRole::IssuersRegistryManager can change trusted issuers.

#### Storage
- `trusted_issuers`: Map<Addr, TrustedIssuer>
Expand All @@ -92,21 +102,23 @@ Manages the list of trusted claim issuers.

### 5. Claim Topics Registry

Stores the required claim topics for token eligibility.
Stores the required claim topics for token eligibility. It is used for compliance. Only those with role OwnerRole::ClaimRegistryManager can change this.

#### Storage
- `required_claim_topics`: Vec<u32>
- `token_claim_topics`: Vec<u32>
- Token addresses are mapped to claims
- Claim is defined by a topic uint128 and an active bool

#### Execute
- `add_claim_topic(topic: u32) -> Result<Response>`
- `remove_claim_topic(topic: u32) -> Result<Response>`

#### Query
- `get_required_claim_topics() -> GetRequiredClaimTopicsResponse`
- `get_claims_for_token() -> StdResult<Vec<Uint128>>`

### 6. Modular Compliance

Implements transfer restriction rules.
Implements transfer restriction rules. Only OwnerRole::ComplianceManager can execute changes. For now country compliance and claims compliance are the ones in use.

#### Storage
- `modules`: Vec<Addr>
Expand Down
221 changes: 221 additions & 0 deletions contracts-review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
# General
## Deploy order
- OwnerRoles
- AgentRoles (weirdly not used by others)
- TrustedIssuers (needs owner roles)
- ClaimTopics (needs owner roles)
- OnChainId (needs trusted issuer)
- ComplianceRegistry (needs owner roles)
- ComplianceClaims (needs chainId, owner roles and claim topics)
- ComplianceCountry (needs chainId and owner roles)
- CWBase (needs compliance registry)

# Owner roles
- Stores owner, there is only a single one
- Adds verification if a specific address her a specific owner role
- Lets owner add other addresses with specific owner roles
- Stores compliance, issuer and claim registries
- IssuersRegistryManagers can add/remove trusted issuers
- ClaimRegistryManagers can add/remove topics
- Looks like unfinished center hub

## Owner roles
```rust
pub enum OwnerRole {
OwnerAdmin,
RegistryAddressSetter,
ComplianceSetter,
ComplianceManager,
ClaimRegistryManager,
IssuersRegistryManager,
TokenInfoManager,
}
```

# Agent roles
- Very similar to owner roles but with agent roles
- Supply Modifiers can do mint/burn
- Transfer manager can do transfer from
- Looks like unfinished center hub
- Has placeholder implementations
- Is transfer allowed
- can transfer
- can receive
```rust
pub enum AgentRole {
SupplyModifiers,
Freezers,
TransferManager,
RecoveryAgents,
ComplianceAgent,
WhiteListManages,
AgentAdmin,
}
```

# Trusted issuer
- Checks if an address is a trusted issuer
- They are tied with a vector of claim topics
- OwnerRole::IssuersRegistryManager can change list

# on chain Identity
- Holds address, country, keys and claims for an identity
- ManagementKey can change stuff
- Needs to check if an user is trusted to allow changes to execute remove/add claims
- Centralizes that
- I dont understand fully how to use this contract
- Do a centralized trusted add other identities? They add themselves?

## Key types
- I dont quite get the key types
```rust
pub enum KeyType {
// 1: MANAGEMENT keys, which can manage the identity
ManagementKey,
// 2: EXECUTION keys, which perform actions in this identities name (signing, logins, transactions, etc.)
ExecutionKey,
// 3: CLAIM signer keys, used to sign claims on other identities which need to be revokable.
ClaimSignerKey,
// 4: ENCRYPTION keys, used to encrypt data e.g. hold in claims.
EncryptionKey,
}
```

# Compliance contracts
- Limit usage of a given contract
- I.e restrict US for cw20

## Compliance Registry
- Handles compliance modules
- When checking if compliant, checks every submodule for valid compliance
- Reqs owner roles
- Only compliance manager can change stuff

## Compliance country restriction
- Restricts which countries comply
- Only compliance manager can add or remove restrictions
- Queries identities' country to check if valid
- Utilizes a contract that holds identity addresses
- OnChainId handles identities

## Compliance claims
- Restricts usage based on claim topics
- Only query to check claims and compliance
- Compliance checks the claim topics

### Claim Topics
- Holds token address <> topic association
- Claims are a topic + active bool
- ClaimRegistryManager can change topics
- `I didn't quite get this`

# CW20 base
## Optionals
Full info: https://github.com/CosmWasm/cw-plus/blob/main/packages/cw20/README.md
- Mintable
- Allows query of Minter
- Allowance
- Allows query of allowance
- Enumerable
- Allows queries of 'all'
- Marketing
- Allows more metadata info (description, logo)
- Download logo

## Compliance
- A token address is stored
- It is used to send a message to that address, to check compliance
- Via smart wasm query
- On every burn, transfer, mint and sent
- It checks if the from, to and amount complies

# Yet to Review
- Missing Executes of CW20
- Just checked instantiate
- Usage test


# Flows
A tool centralizes txs of the tokens

We need to understand how to do these flows
## Deploy
Owner can issue a pool
- Pool is a trusted issuers
- Can receive sells and send out buys
## Register KYC
## Buy
- Users enters a website
- They got through a KYC
- To buy they will go through a DEX
- A liquidity pool that is trusted
- Both the pool and the buyer will need to have a topic level that matches one for the tokens
## Sell
- Goes from pool to buyer

## Questions
- how do we buy/sell assets into this?


# Enzo's experiences
## Economic rights
- Can hold the token but other person can claim things for you

## Swap place
- Listing and minting
- Swap: Takes best price and match
- Listing: lists sell/buys

## Proof of reserve
- Users can ask for proof of reserves
- Contracts have restrictions
- Tokens needs to have a link to the rights
- We, as holders, need to have custody and proof of it
- Else we can be sued

## Living on the chain
- If you move to another chain, it will lose it's value
- No longer tied in the contracts
- If they hold a copy, then it will just be mirrored
- Would need to be copied

## Money Laundry
- Compliance should have a way to deal with possible MLs

## What does plume do?
- https://plume.org/


# Current Direction
1. Deploy RWA contracts
2. Deploy astroport environment (DEX contracts)
3. Deploy preparations for RWA
4. Create trusted issuer
- Backend connects issuers to claims
5. Create a pool between the RWA token and MockUSDT
- Need to check if Mock usdt (it is an ERC20 and needs to be native to the chain)
- Pool needs to be a trusted issuer
6. Users should be able to claim
- Go to RWA page
- Can see tokens but not buy
- Sign up KYC to become trusted
- Can do swaps

Notes
- We will need to interact via cosmwasm precompile
- [Astroport](https://astroport.fi/) has a lot of flexibility on tokens used
- This is a direction, we need to make a proper plan in the future

## Problems
- Only Cosmos addresses are valid via compliance?
- How can we add EVM users to that? Will EVM work out the bat
- Wrap the cosm?
- If this gets out of these contracts, it loses compliance
- Swap can only be done between two trusted issuers
- Do we want swap?
- New assets are done by hand
- CW20 contract is not enforcing roles correctly
- No mention to yield, distribution and so on
- Are allowances ok?
- Compliance registry has no method to list compliances
- Add always overwrites if applying to same token/name
2 changes: 1 addition & 1 deletion contracts/claim-topics/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub fn instantiate(
.api
.addr_validate(msg.owner_roles_address.as_ref())
.map_err(|e| ContractError::InvalidAddress {
reason: format!("Invalid owner address: {}", e),
reason: format!("Invalid owner address: {e}"),
})?;

OWNER_ROLES_ADDRESS.save(deps.storage, &owner_addr)?;
Expand Down
4 changes: 2 additions & 2 deletions contracts/cw20-base/src/allowances.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ mod tests {
use cw20::{Cw20Coin, TokenInfoResponse};

use crate::contract::{execute, instantiate, query_balance, query_token_info};
use crate::msg::{ExecuteMsg, InstantiateMsg, InstantiateTokenInfo, Registeries};
use crate::msg::{ExecuteMsg, InstantiateMsg, InstantiateTokenInfo, Registries};

fn get_balance<T: Into<String>>(deps: Deps, address: T) -> Uint128 {
query_balance(deps, address.into()).unwrap().balance
Expand All @@ -285,7 +285,7 @@ mod tests {
mint: None,
marketing: None,
},
registeries: Registeries {
registries: Registries {
compliance_address: MockApi::default().addr_make("compliance_addr").to_string(),
},
};
Expand Down
Loading
Loading