Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CCIP-022: CityCoins Treasury Redemption #71

Merged
merged 66 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
3ee5cca
fix: add starting code for ccip022 proposal
whoabuddy May 2, 2024
92e3f33
fix: add draft of redemption contract from ccip-020
whoabuddy May 4, 2024
27db7ba
fix: update contract naming and calls for NYC
whoabuddy May 13, 2024
05389b5
fix: update contract for just nyc redemptions
whoabuddy May 13, 2024
87169d5
fix: correct syntax errors
friedger May 14, 2024
5827a7e
Merge pull request #72 from citycoins/fix/ccip022-syntax
whoabuddy May 14, 2024
106794c
fix: add mainnet contract addresses in comments
whoabuddy May 14, 2024
613b35b
fix: prevent multiple claims, verify balance, print info
whoabuddy May 14, 2024
551bc01
fix: small improvements, cleanup comments
whoabuddy May 14, 2024
6007e45
fix: apply suggestions from @friedger
whoabuddy May 14, 2024
d26ffbb
fix: playing with workflow and clarinet versions
whoabuddy May 14, 2024
61a243e
fix: update legacy tests to use older Clarinet.toml
whoabuddy May 14, 2024
c1df83b
fix: update testing strategy
whoabuddy May 20, 2024
8a1f7c1
fix: add model and tests for ccip022
whoabuddy May 20, 2024
dd1dbb0
chore: code cleanup
whoabuddy May 21, 2024
ab7be27
fix: print redemption info in initialize fn
whoabuddy May 21, 2024
a430f4a
fix: add test outline in comments
whoabuddy May 21, 2024
891249f
fix: setup test model for ccd012
whoabuddy May 21, 2024
0aab049
fix: add first two tests, simplify model name
whoabuddy May 21, 2024
6dc4a86
chore: code cleanup
whoabuddy May 21, 2024
7e3c717
chore: code cleanup, test prep
whoabuddy May 21, 2024
20d0262
fix: use address not tx-sender
whoabuddy May 21, 2024
8bad228
fix: update error numbers to 22XXX
whoabuddy May 21, 2024
d55e92a
fix: start adding tests
whoabuddy May 22, 2024
6840d24
fix: use wallet besides deployer for cumulative test
whoabuddy May 22, 2024
6457b0a
fix: update test contracts to simulate more scenarios
whoabuddy May 22, 2024
a19fccc
fix: add moar tests
whoabuddy May 22, 2024
048064a
fix: cleanup failing test, skip ext
whoabuddy May 22, 2024
a186677
fix: starting to test the math
whoabuddy May 22, 2024
e7e253d
fix: update test assertions for redeemBlock
whoabuddy May 22, 2024
c3c1c72
fix: match redemption amounts with contract values
whoabuddy May 22, 2024
79a80f2
chore: remove extra console logging
whoabuddy May 29, 2024
f287f45
fix: create new token to simulate v1 nyc
whoabuddy May 29, 2024
4327fe2
fix: use new nyc-v1 with 0 decimals instead of mia
whoabuddy May 29, 2024
160c247
fix: add tests for v1/v2 tokens only
whoabuddy May 29, 2024
69dd5d1
fix: move parsing function to common utils
whoabuddy May 29, 2024
2c033a9
fix: add test proposal to mint/stack v2 NYC through deployer
whoabuddy May 29, 2024
686b793
fix: update print event to match latest details
whoabuddy May 29, 2024
76b36d8
fix: add test for second claim after unstacking
whoabuddy May 29, 2024
67711c8
chore: variable name change
whoabuddy May 29, 2024
8946512
fix: add fixed point math helpers
whoabuddy May 29, 2024
5b17a15
fix: total supply should be >0 for both v1 and v2
whoabuddy May 29, 2024
12d9582
fix: move redemption ratio calculation to private fn
whoabuddy May 29, 2024
4e1861b
fix: add check for burned tokens
whoabuddy May 29, 2024
122ef6e
fix: rework redemption ratio calculations
whoabuddy May 30, 2024
fd0fc5d
fix: modify redemption ratio calculation and usage
whoabuddy May 31, 2024
099de69
fix: use optional for ratio calculation, update test formatting
whoabuddy May 31, 2024
8ce6d72
chore: update deps
whoabuddy May 31, 2024
c46bc8d
fix: update contract logic based on test results, fix tests for claims
whoabuddy May 31, 2024
f392ced
chore: cleanup console logging, check all tests pass
whoabuddy May 31, 2024
3497450
fix: add totalRedeemed var for amount transferred from contract
whoabuddy Jun 5, 2024
a805e9a
fix: update print format per Clarity WG discussion
whoabuddy Jun 5, 2024
6d49347
chore: separate legacy and regular testing jobs
whoabuddy Jun 5, 2024
ec4c0f8
fix: add test to verify redemption ratio and contract balance after c…
whoabuddy Jun 12, 2024
41ef321
fix: clean up and consolidate functions
whoabuddy Jun 12, 2024
1135d9c
fix: upload cache of requirements files for testing structure
whoabuddy Jun 12, 2024
c02cf90
fix: update job name for better display of legacy test suite
whoabuddy Jun 12, 2024
49a7897
fix: add additional users, mint supply over 5B to simulate current
whoabuddy Jun 12, 2024
325fc86
fix: update test to iterate and check contract, user, and ratios
whoabuddy Jun 12, 2024
04358b5
fix: update expected print event format and related test
whoabuddy Jun 12, 2024
db24f99
fix: add missing test for trying to enable extension twice
whoabuddy Jun 12, 2024
574af4a
fix: support edge case of claim being greater than contract balance
whoabuddy Jun 19, 2024
503f4d2
fix: move calculation for edge case to get-redemption-for-balance
whoabuddy Jun 19, 2024
534d55f
fix: add comments to explain balance calculation
whoabuddy Jun 19, 2024
4122d74
chore: clean up test console logging
whoabuddy Jun 19, 2024
a44d7c9
fix: add ccip-022 hash
whoabuddy Jun 19, 2024
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
186 changes: 186 additions & 0 deletions contracts/extensions/ccd012-redemtpion-nyc.clar
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
;; Title: CCD012 - CityCoin Redemption (NYC)
;; Version: 1.0.0
;; Summary: A redemption extension that allows users to redeem CityCoins for a portion of the city treasury.
;; Description: An extension that provides the ability to claim a portion of the city treasury in exchange for CityCoins.

;; TRAITS

(impl-trait .extension-trait.extension-trait)

;; CONSTANTS

;; error codes
(define-constant ERR_UNAUTHORIZED (err u12000))
(define-constant ERR_PANIC (err u12001))
(define-constant ERR_GETTING_TOTAL_SUPPLY (err u12002))
(define-constant ERR_GETTING_REDEMPTION_BALANCE (err u12003))
(define-constant ERR_ALREADY_ENABLED (err u12004))
(define-constant ERR_NOT_ENABLED (err u12005))
(define-constant ERR_BALANCE_NOT_FOUND (err u12006))
(define-constant ERR_NOTHING_TO_REDEEM (err u12007))

;; helpers
(define-constant MICRO_CITYCOINS (pow u10 u6)) ;; 6 decimal places

;; DATA VARS

(define-data-var redemptionsEnabled bool false)
(define-data-var blockHeight uint u0)
(define-data-var totalSupply uint u0)
(define-data-var contractBalance uint u0)
(define-data-var redemptionRatio uint u0)

;; DATA MAPS

;; track totals per principal
(define-map RedemptionClaims
principal ;; address
uint ;; total redemption amount
)

;; PUBLIC FUNCTIONS

(define-public (is-dao-or-extension)
(ok (asserts! (or (is-eq tx-sender .base-dao)
(contract-call? .base-dao is-extension contract-caller)) ERR_UNAUTHORIZED
))
)

(define-public (callback (sender principal) (memo (buff 34)))
(ok true)
)

;; initialize contract after deployment to start redemptions
(define-public (initialize-redemptions)
(let
(
;; MAINNET: TODO
(nycTotalSupplyV1 (unwrap! (contract-call? .newyorkcitycoin-token get-total-supply) ERR_PANIC))
(nycTotalSupplyV2 (unwrap! (contract-call? .newyorkcitycoin-token-v2 get-total-supply) ERR_PANIC))
(nycTotalSupply (+ (* nycTotalSupplyV1 MICRO_CITYCOINS) nycTotalSupplyV2))
(nycRedemptionBalance (as-contract (stx-get-balance tx-sender)))
)
;; check if sender is DAO or extension
(try! (is-dao-or-extension))
;; check that total supply is greater than 0
(asserts! (and (> nycTotalSupplyV1 u0) (> nycTotalSupplyV2 u0)) ERR_GETTING_TOTAL_SUPPLY)
whoabuddy marked this conversation as resolved.
Show resolved Hide resolved
;; check that redemption balance is greater than 0
(asserts! (> nycRedemptionBalance u0) ERR_GETTING_REDEMPTION_BALANCE)
;; check if redemptions are already enabled
(asserts! (not (var-get redemptionsEnabled)) ERR_ALREADY_ENABLED)
;; record current block height
(var-set blockHeight block-height)
;; record total supply at block height
(var-set totalSupply nycTotalSupply)
;; record contract balance at block height
(var-set contractBalance nycRedemptionBalance)
;; calculate redemption ratio
(var-set redemptionRatio (/ nycRedemptionBalance nycTotalSupply))
;; set redemptionsEnabled to true, can only run once
(ok (var-set redemptionsEnabled true))
)
)

(define-public (redeem-nyc)
(let
(
(userAddress tx-sender)
(balanceV1 (unwrap! (contract-call? .newyorkcitycoin-token get-balance userAddress) ERR_BALANCE_NOT_FOUND))
(balanceV2 (unwrap! (contract-call? .newyorkcitycoin-token-v2 get-balance userAddress) ERR_BALANCE_NOT_FOUND))
(totalBalance (+ (* balanceV1 MICRO_CITYCOINS) balanceV2))
(redemptionAmount (unwrap! (get-redemption-for-balance totalBalance) ERR_NOTHING_TO_REDEEM))
(redemptionClaims (default-to u0 (get-redemption-amount-claimed userAddress)))
)
;; check if redemptions are enabled
(asserts! (var-get redemptionsEnabled) ERR_NOT_ENABLED)
;; check that redemption amount is > 0
(asserts! (> redemptionAmount u0) ERR_NOTHING_TO_REDEEM)
;; burn NYC
(and (> u0 balanceV1) (try! (contract-call? .newyorkcitycoin-token burn balanceV1 userAddress)))
(and (> u0 balanceV2) (try! (contract-call? .newyorkcitycoin-token-v2 burn balanceV2 userAddress)))
;; transfer STX
(try! (as-contract (stx-transfer? redemptionAmount tx-sender userAddress)))
;; update redemption claims
(map-set RedemptionClaims userAddress (+ redemptionClaims redemptionAmount))
;; return redemption amount
(ok redemptionAmount)
)
)

;; READ ONLY FUNCTIONS

(define-read-only (is-redemption-enabled)
(var-get redemptionsEnabled)
)

(define-read-only (get-redemption-block-height)
(var-get blockHeight)
)

(define-read-only (get-redemption-total-supply)
(var-get totalSupply)
)

(define-read-only (get-redemption-contract-balance)
(var-get contractBalance)
)

(define-read-only (get-redemption-ratio)
(var-get redemptionRatio)
)

;; aggregate all exposed vars above
(define-read-only (get-redemption-info)
{
redemptionsEnabled: (var-get redemptionsEnabled),
blockHeight: (var-get blockHeight),
totalSupply: (var-get totalSupply),
contractBalance: (var-get contractBalance),
redemptionRatio: (var-get redemptionRatio)
}
)

(define-read-only (get-nyc-balances)
(let
(
(balanceV1 (unwrap! (contract-call? .newyorkcitycoin-token get-balance tx-sender) ERR_BALANCE_NOT_FOUND))
(balanceV2 (unwrap! (contract-call? .newyorkcitycoin-token-v2 get-balance tx-sender) ERR_BALANCE_NOT_FOUND))
(totalBalance (+ (* balanceV1 MICRO_CITYCOINS) balanceV2))
)
(ok {
balanceV1: balanceV1,
balanceV2: balanceV2,
totalBalance: totalBalance
})
)
)

(define-read-only (get-redemption-for-balance (balance uint))
(begin
(asserts! (var-get redemptionsEnabled) none)
(some (* balance (var-get redemptionRatio)))
)
)

(define-read-only (get-redemption-amount-claimed (address principal))
(map-get? RedemptionClaims tx-sender)
)

;; aggregate all exposed vars above
(define-read-only (get-user-redemption-info)
(let
(
(nycBalances (try! (get-nyc-balances)))
(redemptionAmount (default-to u0 (get-redemption-for-balance (get totalBalance nycBalances))))
(redemptionClaims (default-to u0 (get-redemption-amount-claimed tx-sender)))
)
(ok {
address: tx-sender,
nycBalances: nycBalances,
redemptionAmount: redemptionAmount,
redemptionClaims: redemptionClaims
})
)
)

;; PRIVATE FUNCTIONS
Loading