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

Convertible Deposits #29

Draft
wants to merge 143 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
143 commits
Select commit Hold shift + click to select a range
053cb32
Create CDsEmissions.sol
chefomi Nov 29, 2024
56b8f3b
Update CDsEmissions.sol
chefomi Nov 29, 2024
49ecd6d
Auctioneer + Facility
chefomi Dec 4, 2024
356af03
updates
chefomi Dec 6, 2024
4d55f12
integrate with emissions manager
chefomi Dec 7, 2024
61a7377
Fix compilation errors
0xJem Dec 9, 2024
9068ba0
chore: linting
0xJem Dec 9, 2024
e41276b
Add custom error to contracts. Add missing CDFacility parameter to CD…
0xJem Dec 9, 2024
74ebfa4
Extract CDAuctioneer into interface
0xJem Dec 9, 2024
fb68663
Fix compilation errors for EmissionManager test
0xJem Dec 9, 2024
2f2a0de
Add cdUSDS parameter to CDFacility. Extract cdUSDS into interface.
0xJem Dec 9, 2024
4797b13
Fix naming consistency with debt/deposit. Add missing parameter to de…
0xJem Dec 13, 2024
a6dacc8
Create interface for convertible deposit facility
0xJem Dec 13, 2024
6291399
Fix compile errors
0xJem Dec 13, 2024
55397f8
Fix licenses
0xJem Dec 13, 2024
7953b93
Interface for a proposed CDEPO module
0xJem Dec 13, 2024
43ca59c
Update description
0xJem Dec 13, 2024
c3a7ee8
Add module for convertible deposit terms
0xJem Dec 16, 2024
349c671
Add CTERM events
0xJem Dec 16, 2024
6b20f80
WIP implementation of CDEPO
0xJem Dec 16, 2024
5536d54
First pass a CDEPO
0xJem Dec 16, 2024
9fb539c
First pass at implementation of CTERM
0xJem Dec 16, 2024
e3dcecc
Add a permissioned function to CDEPO to redeem CD tokens for assets. …
0xJem Dec 16, 2024
42a6d68
Rename CTERM to CDPOS
0xJem Dec 16, 2024
be52b09
Shift CDAuctioneer to use new CDFacility interface
0xJem Dec 16, 2024
2c28d33
Check CD token before converting/reclaiming using a CD position
0xJem Dec 17, 2024
f1dbb75
First pass at SVG for CD positions
0xJem Dec 17, 2024
6b9888f
Extract previewBid functionality
0xJem Dec 17, 2024
fddaa3b
Docs
0xJem Dec 17, 2024
e3ad735
Add isExpired getter to CDPOS
0xJem Dec 18, 2024
77e2787
Adjust CDPOS SVG
0xJem Dec 18, 2024
abf0b3c
Wrote helper function to convert a fixed-point integer into a decimal…
0xJem Dec 18, 2024
7ba544a
Add conversion price and remaining deposit to the SVG and traits
0xJem Dec 18, 2024
724b2b5
Add setter
0xJem Dec 18, 2024
51648f0
Docs
0xJem Dec 18, 2024
1719af0
Add previewConvert to CDPOS
0xJem Dec 18, 2024
4be3322
Add stubs for CDPOS tests
0xJem Dec 18, 2024
497ed1c
Add owner back to position struct
0xJem Dec 18, 2024
f293e5e
Implement tests for CDPOS.create()
0xJem Dec 18, 2024
6571d51
CDPOS tests for create/update/split
0xJem Dec 19, 2024
6c4fcac
CDPOS tests for wrap/unwrap
0xJem Dec 19, 2024
95ad4be
Clarify decimal scale in docs, tests for previewConvert
0xJem Dec 19, 2024
0520eba
Tests for setDisplayDecimals and transferFrom
0xJem Dec 19, 2024
d8d89bf
Handling of transferFrom in CDPOS
0xJem Dec 19, 2024
27a3695
Fix handling of mint checks
0xJem Dec 19, 2024
875cdd9
Remove redundant tests
0xJem Dec 19, 2024
dbd3f6e
CDEPO: rename burn() to reclaim() and adjust logic around spending to…
0xJem Dec 19, 2024
fcd4e3d
CDEPO: test stubs
0xJem Dec 19, 2024
908a641
CDEPO: tests for mint/mintTo/previewMint, rename burn rate to reclaim…
0xJem Dec 19, 2024
fb9bf7e
CDEPO: setReclaimRate tests
0xJem Dec 19, 2024
56cabb2
CDEPO: mint test fixes
0xJem Dec 19, 2024
85e73e9
CDEPO: more tests
0xJem Dec 19, 2024
e73bf8e
CDEPO: more tests, use safeTransfer/safeApprove, clarify allowance
0xJem Dec 20, 2024
d9b3679
CDEPO: tests and impl fixes for rounding, redeem tests
0xJem Dec 20, 2024
4bbde8a
CDEPO: sweepYield tests
0xJem Dec 20, 2024
e98f502
CDFacility: test stubs
0xJem Dec 20, 2024
c4f56c2
CDEPO: add mint/reclaim/redeem -For functions, add spending allowance…
0xJem Dec 20, 2024
2aca51a
CDFacility: test updates
0xJem Dec 20, 2024
0cf6892
Add preview functions to CD facility
0xJem Dec 23, 2024
21580db
CD Facility: role must be lowercase. Add previewConvert and previewRe…
0xJem Dec 23, 2024
3fb895c
CDFacility: convert tests
0xJem Dec 23, 2024
1820d39
CDFacility: more comprehensive tests
0xJem Dec 23, 2024
34307b4
CDFacility: better handling of ownership check
0xJem Dec 23, 2024
e9146a3
CDFacility: WIP previewReclaim tests
0xJem Dec 23, 2024
20571b2
CDFacility: tests for convert, reclaim
0xJem Dec 26, 2024
54795bb
chore: linting
0xJem Dec 30, 2024
fe8e09e
CDAuctioneer: add docs, address logic errors
0xJem Dec 30, 2024
49d0ffd
CDAuctioneer: minor improvements
0xJem Dec 30, 2024
8e2e4bb
CDAuctioneer: rename day -> dayState
0xJem Dec 30, 2024
859b09b
CDAuctioneer: use scale instead of decimals
0xJem Dec 30, 2024
156b140
CDAuctioneer: split updating the current tick out of the getter function
0xJem Dec 30, 2024
2018d4a
CDAuctioneer: reset the day state
0xJem Dec 30, 2024
ab4dcf5
CDAuctioneer: fixes for bidding logic
0xJem Dec 30, 2024
6015163
CDAuctioneer: pull roles into constants, differentiate roles, add rol…
0xJem Dec 31, 2024
0267ede
CDAuctioneer: use basic types in constructor. Make `getUpdatedTick()`…
0xJem Dec 31, 2024
cdb31dd
CDAuctioneer: test stubs
0xJem Dec 31, 2024
9af47bf
CDAuctioneer: tests
0xJem Dec 31, 2024
1be96c3
chore: linting
0xJem Dec 31, 2024
a3e69c9
CDAuctioneer: compiler fixes
0xJem Jan 2, 2025
089f2be
CDAuctioneer: add TODOs for more tests
0xJem Jan 2, 2025
a5190ef
CDAuctioneer: extract function for tick price calculation
0xJem Jan 2, 2025
753251c
CDAuctioneer: tests for setter sanity-checks
0xJem Jan 2, 2025
31162f8
CDAuctioneer: restore previous logic with tick price in getUpdatedTick()
0xJem Jan 2, 2025
7826525
CDAuctioneer: tests for activate/deactivate/setAuctionParameters, fix…
0xJem Jan 2, 2025
2e375b5
CDAuctioneer: WIP getUpdatedTick() tests
0xJem Jan 2, 2025
30f5692
CDAuctioneer: document auction approach and TODOs, based on recent co…
0xJem Jan 3, 2025
ccf52ae
CDAuctioneer: split tick step into a separate variable, change scale …
0xJem Jan 3, 2025
41c88ac
CDAuctioneer: shift time to expiry into standalone variable
0xJem Jan 3, 2025
f2c8c0c
CDAuctioneer: add initialize() function that ensures all state variab…
0xJem Jan 3, 2025
3400c29
CDAuctioneer: test cases for initialize()
0xJem Jan 3, 2025
3296f9e
CDAuctioneer: rename getCurrentTick() to getPreviousTick() and getUpd…
0xJem Jan 3, 2025
6cde285
CDAuctioneer: WIP getCurrentTick() tests and fixes
0xJem Jan 3, 2025
f9e201d
CDAuctioneer: WIP getCurrentTick() tests
0xJem Jan 6, 2025
3bc3259
CDAuctioneer: finish getCurrentTick() tests
0xJem Jan 6, 2025
5c8ec9d
CDAuctioneer: WIP bid() tests
0xJem Jan 6, 2025
f0abf96
CDAuctioneer: return positionId from bid(), add token balance and pos…
0xJem Jan 7, 2025
45c0161
CDAuctioneer: bid() tests
0xJem Jan 7, 2025
98407fe
CDAuctioneer: ensure that bid() refills the tick upon depletion
0xJem Jan 7, 2025
b1480ec
CDAuctioneer: modify previewBid()/bid() to not be greedy if a deposit…
0xJem Jan 7, 2025
00745b1
CDAuctioneer: rename State to AuctionParameters. Test corrections.
0xJem Jan 7, 2025
76d458c
CDAuctioneer: handle edge cases when setting auction parameters
0xJem Jan 7, 2025
7b718c5
chore: fix TODOs
0xJem Jan 7, 2025
fa4b099
CDFacility: contract is disabled upon deployment
0xJem Jan 7, 2025
d736725
CDAuctioneer: incorrect conditional when checking auction parameters.…
0xJem Jan 7, 2025
5cd845b
Fix tests
0xJem Jan 7, 2025
5860096
chore: linting
0xJem Jan 8, 2025
aaaa0f2
CDAuctioneer: TODOs for reducing tick size
0xJem Jan 8, 2025
79e11fd
CDAuctioneer: shift lastUpdate property into tick data structure
0xJem Jan 8, 2025
eb5033d
CDAuctioneer: test fix
0xJem Jan 8, 2025
41893ee
CDAuctioneer: more robust tests and checks for initialized status
0xJem Jan 8, 2025
e570238
chore: linting
0xJem Jan 8, 2025
4ade3a7
CDAuctioneer: add property for the current tick size. Update tests to…
0xJem Jan 8, 2025
4071fc8
CDAuctioneer: WIP halving of tick size after the day target has been …
0xJem Jan 8, 2025
135ffed
CDAuctioneer: finish implementation and tests for adjusting the tick …
0xJem Jan 9, 2025
2663fb0
CDAuctioneer: test stubs for tracking of historical auction results
0xJem Jan 13, 2025
489a672
Merge branch 'develop' into CDsEmissions
0xJem Jan 14, 2025
42420f3
Fix compiler errors
0xJem Jan 14, 2025
80aca68
CDAuctioneer: implement tracking of auction results over a defined pe…
0xJem Jan 14, 2025
7486c69
Propagate auction result changes into EmissionManager. Remove redunda…
0xJem Jan 15, 2025
4289c62
EmissionManager: add missing events, remove redundant error
0xJem Jan 15, 2025
b558772
EmissionManager: avoid global import, remove redundant interface
0xJem Jan 15, 2025
0f89e20
Warn on global import
0xJem Jan 15, 2025
c49ffea
EmissionManager: add VERSION() function
0xJem Jan 15, 2025
7ced7f9
EmissionManager: swap check order
0xJem Jan 15, 2025
854cacd
Test fix
0xJem Jan 15, 2025
ce72f28
EmissionsManager: update tests
0xJem Jan 15, 2025
f5f4955
EmissionManager: add additional test cases for surplus, zero auction …
0xJem Jan 15, 2025
558346d
Add version function to policies
0xJem Jan 15, 2025
0ba0357
CDPOS: fix extraneous characters in tokenURI
0xJem Jan 16, 2025
d9e137f
CDPOS: tests for ERC721 metadata
0xJem Jan 16, 2025
4bba808
chore: linting
0xJem Jan 16, 2025
e0f3f6a
CDPOS: don't wrap position ID and expiry numerical attributes in quotes
0xJem Jan 16, 2025
725a6d4
CDPOS: don't wrap conversion price and remaining deposit in quotes
0xJem Jan 16, 2025
8f2e16f
Case-sensitivity
0xJem Jan 16, 2025
81c8cb4
Audit README
0xJem Jan 16, 2025
611914a
Audit README
0xJem Jan 16, 2025
629ea74
Add sequence diagrams
0xJem Jan 17, 2025
c5edfb1
CDFacility: rename reclaim() -> redeem() to be consistent with CDEPO
0xJem Jan 17, 2025
6ef3679
CDFacility: test stubs for reclaim()
0xJem Jan 17, 2025
6a4c8c0
CDFacility: reclaim() tests
0xJem Jan 17, 2025
923f6c7
CDFacility: implement reclaim/previewReclaim
0xJem Jan 17, 2025
135bf42
CDFacility: more consistent handling of numbers when calculating rede…
0xJem Jan 17, 2025
f2691d8
CDEPO: rename variable
0xJem Jan 17, 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
181 changes: 181 additions & 0 deletions src/policies/CDAuctioneer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.15;

import "src/Kernel.sol";

import {ReentrancyGuard} from "solmate/utils/ReentrancyGuard.sol";
import {ERC20} from "solmate/tokens/ERC20.sol";

import {RolesConsumer, ROLESv1} from "modules/ROLES/OlympusRoles.sol";

import {FullMath} from "libraries/FullMath.sol";

import {CDFacility} from "./CDFacility.sol";

interface CDRC20 {
function mint(address to, uint256 amount) external;
function burn(address from, uint256 amount) external;
function convertFor(uint256 amount) external view returns (uint256);
function expiry() external view returns (uint256);
}

contract CDAuctioneer is Policy, RolesConsumer {
using FullMath for uint256;

// ========== DATA STRUCTURES ========== //

struct State {
uint256 target; // number of ohm per day
uint256 tickSize; // number of ohm in a tick
uint256 minPrice; // minimum tick price
uint256 tickStep; // percentage increase (decrease) per tick
uint256 timeToExpiry; // time between creation and expiry of deposit
uint256 lastUpdate; // timestamp of last update to current tick
}

struct Day {
uint256 deposits; // total deposited for day
uint256 convertable; // total convertable for day
}

struct Tick {
uint256 price;
uint256 capacity;
}

// ========== EVENTS ========== //

// ========== STATE VARIABLES ========== //

Tick public currentTick;
State public state;

uint256 public decimals;

CDFacility public cdFacility;

mapping(uint256 => mapping(uint256 => address)) public cdTokens; // mapping(expiry => price => token)

Day public today;

// ========== SETUP ========== //

constructor(Kernel kernel_) Policy(kernel_) {}

function configureDependencies() external override returns (Keycode[] memory dependencies) {
dependencies = new Keycode[](1);
dependencies[2] = toKeycode("ROLES");

ROLES = ROLESv1(getModuleAddress(dependencies[0]));
}

function requestPermissions()
external
view
override
returns (Permissions[] memory permissions)
{}

// ========== AUCTION ========== //

/// @notice use a deposit to bid for CDs
/// @param deposit amount of reserve tokens
/// @return convertable amount of convertable tokens
function bid(uint256 deposit) external returns (uint256 convertable) {
// update state
currentTick = getCurrentTick();
state.lastUpdate = block.timestamp;

// iterate until user has no more reserves to bid
while (deposit > 0) {
// handle spent/capacity for tick
uint256 amount = currentTick.capacity < convertFor(deposit, currentTick.price)
? state.tickSize
: deposit;
if (amount != state.tickSize) currentTick.capacity -= amount;
else currentTick.price *= state.tickStep / decimals;

// decrement bid and increment tick price
deposit -= amount;
convertable += convertFor(amount, currentTick.price);
}

today.deposits += deposit;
today.convertable += convertable;

// mint amount of CD token
cdFacility.addNewCD(msg.sender, deposit, convertable, block.timestamp + state.timeToExpiry);
}

// ========== VIEW FUNCTIONS ========== //

/// @notice get current tick info
/// @dev time passing changes tick info
/// @return tick info in Tick struct
function getCurrentTick() public view returns (Tick memory tick) {
// find amount of time passed and new capacity to add
uint256 timePassed = block.timestamp - state.lastUpdate;
uint256 newCapacity = (state.target * timePassed) / 1 days;

tick = currentTick;

// decrement price while ticks are full
while (tick.capacity + newCapacity > state.tickSize) {
newCapacity -= state.tickSize;
tick.price *= decimals / state.tickStep;

// tick price does not go below the minimum
// tick capacity is full if the min price is exceeded
if (tick.price < state.minPrice) {
tick.price = state.minPrice;
newCapacity = state.tickSize;
break;
}
}

// decrement capacity by remainder
tick.capacity = newCapacity;
}

/// @notice get amount of cdOHM for a deposit at a tick price
/// @return amount convertable
function convertFor(uint256 deposit, uint256 price) public view returns (uint256) {
return (deposit * decimals) / price;
}

// ========== ADMIN FUNCTIONS ========== //

/// @notice update auction parameters
/// @dev only callable by the auction admin
/// @param newTarget new target sale per day
/// @param newSize new size per tick
/// @param newMinPrice new minimum tick price
function beat(
uint256 newTarget,
uint256 newSize,
uint256 newMinPrice
) external onlyRole("CD_Auction_Admin") returns (uint256 remainder) {
remainder = (state.target > today.convertable) ? state.target - today.convertable : 0;

state = State(
newTarget,
newSize,
newMinPrice,
state.tickStep,
state.timeToExpiry,
state.lastUpdate
);
}

/// @notice update time between creation and expiry of deposit
/// @param newTime number of seconds
function setTimeToExpiry(uint256 newTime) external onlyRole("CD_Admin") {
state.timeToExpiry = newTime;
}

/// @notice update change between ticks
/// @param newStep percentage in decimal terms
function setTickStep(uint256 newStep) external onlyRole("CD_Admin") {
state.tickStep = newStep;
}
}
Loading
Loading