Skip to content

Commit

Permalink
Remove magic. Make things work
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielVF committed Nov 4, 2024
1 parent 9d762b9 commit cbe41fb
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 29 deletions.
77 changes: 55 additions & 22 deletions src/token/OUSD.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ contract OUSD is Governable {
mapping(address => uint256) public isUpgraded;
mapping(address => address) public yieldTo;
mapping(address => address) public yieldFrom;
mapping(address => uint256) public aintMoney;

uint256 private constant RESOLUTION_INCREASE = 1e9;

Expand Down Expand Up @@ -133,9 +132,11 @@ contract OUSD is Governable {
view
returns (uint256)
{
return
_creditBalances[_account] * 1e18 / _creditsPerToken(_account)
- aintMoney[_account];
uint256 baseBalance = _creditBalances[_account] * 1e18 / _creditsPerToken(_account);
if (rebaseState[_account] == RebaseOptions.YieldDelegationTarget) {
return baseBalance - _creditBalances[yieldFrom[_account]];
}
return baseBalance;
}

/**
Expand Down Expand Up @@ -265,16 +266,30 @@ contract OUSD is Governable {
if(newBalance < 0){
revert("Transfer amount exceeds balance"); // Should never trigger
}
if (state == RebaseOptions.YieldDelegationTarget) {
newBalance += aintMoney[account];
}
if (state == RebaseOptions.YieldDelegationSource) {
address target = yieldTo[account];
uint256 targetPrevBalance = balanceOf(target);
uint256 targetNewCredits = _balanceToRebasingCredits(targetPrevBalance + newBalance);
rebasingCreditsDiff = int256(targetNewCredits) - int256(_creditBalances[target]);

_creditBalances[account] = newBalance;
_creditBalances[target] = targetNewCredits;

if(nonRebasingCreditsPerToken[account]!=1e18){ // Todo, should be removeable
nonRebasingCreditsPerToken[account] = 1e18;
}

} else if (state == RebaseOptions.YieldDelegationTarget) {
uint256 newCredits = _balanceToRebasingCredits(newBalance + _creditBalances[yieldFrom[account]]);
rebasingCreditsDiff = int256(newCredits) - int256(_creditBalances[account]);
_creditBalances[account] = newCredits;

if(_isNonRebasingAccount(account)){
} else if(_isNonRebasingAccount(account)){
nonRebasingSupplyDiff = balanceChange;
if(nonRebasingCreditsPerToken[account]!=1e27){
nonRebasingCreditsPerToken[account] = 1e27;
if(nonRebasingCreditsPerToken[account]!=1e18){
nonRebasingCreditsPerToken[account] = 1e18;
}
_creditBalances[account] = newBalance * 1e9;
_creditBalances[account] = newBalance;
} else {
uint256 newCredits = _balanceToRebasingCredits(newBalance);
rebasingCreditsDiff = int256(newCredits) - int256(_creditBalances[account]);
Expand Down Expand Up @@ -475,7 +490,7 @@ contract OUSD is Governable {
if (_creditBalances[_account] == 0) {
// Since there is no existing balance, we can directly set to
// high resolution, and do not have to do any other bookkeeping
nonRebasingCreditsPerToken[_account] = 1e27;
nonRebasingCreditsPerToken[_account] = 1e18;
} else {
// Migrate an existing account:

Expand Down Expand Up @@ -544,8 +559,8 @@ contract OUSD is Governable {

// Acount
rebaseState[msg.sender] = RebaseOptions.OptOut;
nonRebasingCreditsPerToken[msg.sender] = 1e27;
_creditBalances[msg.sender] = balance * 1e9;
nonRebasingCreditsPerToken[msg.sender] = 1e18;
_creditBalances[msg.sender] = balance;

// Globals
nonRebasingSupply += balance;
Expand Down Expand Up @@ -604,25 +619,43 @@ contract OUSD is Governable {
, "Blocked by existing yield delegation");
require(!_isNonRebasingAccount(to), "Must delegate to a rebasing account");
require(_isNonRebasingAccount(from), "Must delegate from a non-rebasing account");
// Todo, tighter scope on above checks, partucularly the state

yieldTo[from] = to;
yieldFrom[to] = from;
rebaseState[from] = RebaseOptions.YieldDelegationSource;
rebaseState[to] = RebaseOptions.YieldDelegationTarget;

uint256 fromAmount = balanceOf(from);
nonRebasingSupply -= fromAmount;
aintMoney[to] = fromAmount;
(int256 rebasingCreditsDiff, int256 nonRebasingSupplyDiff)
= _adjustAccount(to, int256(fromAmount));
_adjustGlobals(rebasingCreditsDiff, nonRebasingSupplyDiff);

uint256 balance = balanceOf(from);
uint256 credits = _balanceToRebasingCredits(balance);
// Local
_creditBalances[from] = balance;
_creditBalances[to] += credits;

// Global
nonRebasingSupply -= balance;
_rebasingCredits += credits;
}

function undelegateYield(address from) external onlyGovernor() {
require(yieldTo[from] != address(0), "");
address to = yieldTo[from];
uint256 fromBalance = balanceOf(from);
uint256 toBalance = balanceOf(to);
uint256 toCreditsBefore = _creditBalances[to];
uint256 toNewCredits = _balanceToRebasingCredits(toBalance);

yieldFrom[yieldTo[from]] = address(0);
yieldTo[from] = address(0);
// Todo: change rebase state
rebaseState[from] = RebaseOptions.OptOut;
_creditBalances[from] = fromBalance;
nonRebasingCreditsPerToken[from] = 1e18;

rebaseState[to] = RebaseOptions.OptIn;
_creditBalances[to] = toNewCredits;
nonRebasingCreditsPerToken[to] = 0; // Should be non-needed

nonRebasingSupply += fromBalance;
_rebasingCredits -= (toCreditsBefore - toNewCredits); // Should always go down or stay the same
}
}
58 changes: 51 additions & 7 deletions test/OUSD.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,24 @@ contract CounterTest is Test {


assertEq(ousd.nonRebasingSupply(), 2000 ether);
assertEq(ousd.balanceOf(collector), 1000 ether, "Collector should be unchanged after rebaseOptIn");
console.log("-> DelegateYield");
ousd.delegateYield(pool, collector);
assertEq(ousd.nonRebasingSupply(), 1000 ether, "delegate should decrease nonrebasing");
assertEq(ousd.totalSupply(), 5000 ether);
assertEq(ousd.balanceOf(pool), 1000 ether);
assertEq(ousd.balanceOf(collector), 1000 ether);
assertEq(ousd.balanceOf(pool), 1000 ether, "Pool balance should be unchanged");
assertEq(ousd.balanceOf(collector), 1000 ether, "Collector should be unchanged after delegate");
}

function _show() internal {
console.log(" ..totalSupply: ", ousd.totalSupply());
console.log(" ..nonRebasingSupply: ", ousd.nonRebasingSupply());
console.log(" ..rebasingCredits: ", ousd.rebasingCreditsHighres());
console.log(" ..rebasingCreditsPerToken: ", ousd.rebasingCreditsPerTokenHighres());
console.log(" ..expectedRebasingBalance: ", ousd.rebasingCreditsHighres()/ousd.rebasingCreditsPerTokenHighres());
console.log(" ....POOL:", ousd.balanceOf(pool));
console.log(" ....COLLECTOR:", ousd.balanceOf(collector));
console.log(" ....MATT:", ousd.balanceOf(matt));
}

function test_ChangeSupply() public {
Expand Down Expand Up @@ -119,13 +125,51 @@ contract CounterTest is Test {
}

function testDelegateYield() public {
console.log("testDelegateYield");
_show();

console.log(ousd.totalSupply()/1e18);
console.log(ousd.balanceOf(matt)*1/1e18);
console.log("Supply Up, first");
ousd.changeSupply(ousd.totalSupply() + 2000 ether);
_show();
assertEq(ousd.balanceOf(matt), 1500 ether);
assertEq(ousd.balanceOf(pool), 1000 ether);
assertEq(ousd.balanceOf(collector), 2000 ether, "Collecter should have earned both yields");
assertEq(ousd.nonRebasingSupply(), 1000 ether);

console.log("Transfer 1500 to pool");
vm.prank(matt);
ousd.transfer(pool, 1000 ether);
_show();
assertEq(ousd.balanceOf(matt), 500 ether);
assertEq(ousd.balanceOf(pool), 2000 ether, "pool should have 1500 + 1000");
assertEq(ousd.balanceOf(collector), 2000 ether, "collector should not increase on transfer to pool");
assertEq(ousd.nonRebasingSupply(), 1000 ether, "Non rebasing supply");

ousd.changeSupply(ousd.totalSupply() + 1000 ether);
assertEq(ousd.balanceOf(matt), 1250 ether);
assertEq(ousd.balanceOf(collector), 1500 ether, "Collecter should have earned both yields");
console.log("Change supply");
assertEq(ousd.nonRebasingSupply(), 1000 ether, "Non rebasing supply");
ousd.changeSupply(ousd.totalSupply() + 3000 ether);
_show();
assertEq(ousd.balanceOf(pool), 2000 ether);
assertEq(ousd.balanceOf(collector), 4000 ether);

console.log("Remove delegation");
ousd.undelegateYield(pool);
_show();
assertEq(ousd.balanceOf(pool), 2000 ether);
assertEq(ousd.balanceOf(collector), 4000 ether);

console.log("Transfer from collector");
vm.prank(collector);
ousd.transfer(nonrebasing, 1000 ether);
_show();
assertEq(ousd.balanceOf(collector), 3000 ether);

console.log("Change supply");
assertEq(ousd.nonRebasingSupply(), 4000 ether, "Non rebasing supply");
ousd.changeSupply(ousd.totalSupply() + 3000 ether);
_show();
assertEq(ousd.balanceOf(pool), 2000 ether);
assertEq(ousd.balanceOf(collector), 4500 ether);

}

Expand Down

0 comments on commit cbe41fb

Please sign in to comment.