Skip to content

Commit

Permalink
Merge pull request #73 from 0xIntuition/ENG-1556-redemptions
Browse files Browse the repository at this point in the history
ENG-1556: Create use cases in/out for redeemAtom
  • Loading branch information
cgmello authored May 24, 2024
2 parents f3e8d54 + fa3e68d commit c65bed1
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 8 deletions.
63 changes: 60 additions & 3 deletions _playground/ethmultivault.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
minShare = Web3.to_wei(Decimal('0.0000000000001'), 'ether')
protocolFee = 100 # 1%
entryFee = 500 # 5%
exitFee = 500 # 5%
feeDenominator = 10000

# Costs
Expand All @@ -40,11 +41,11 @@ def createAtom(value: Decimal) -> tuple[Decimal, Decimal, Decimal, Decimal, Deci

# Addresses
atomWalletShares = Decimal(atomWalletInitialDepositAmount)
zeroWalletShares = minShare
protocolVaultAssets = Decimal(atomCreationProtocolFee) + Decimal(protocolFeeAmount)

return (userShares, totalShares, totalAssets, atomWalletShares, protocolVaultAssets)


def createTriple(value: Decimal) -> tuple[Decimal, Decimal, Decimal, Decimal, Decimal, Decimal, Decimal, Decimal, Decimal]:
# Variables
userDeposit = value - tripleCost
Expand All @@ -70,7 +71,6 @@ def createTriple(value: Decimal) -> tuple[Decimal, Decimal, Decimal, Decimal, De
totalSharesAtomVault = userSharesAfterTotalFees

# Addresses
#zeroWalletShares = Decimal(2) * Decimal(minShare)
protocolVaultAssets = Decimal(tripleCreationProtocolFee) + Decimal(protocolFeeAmount)

return (userSharesPositiveVault,
Expand All @@ -83,6 +83,7 @@ def createTriple(value: Decimal) -> tuple[Decimal, Decimal, Decimal, Decimal, De
totalAssetsAtomVault,
protocolVaultAssets)


def depositAtom(value: Decimal, totalAssets: Decimal, totalShares: Decimal) -> tuple[Decimal, Decimal, Decimal, Decimal]:
# Variables
protocolFeeAmount = math.ceil(value * Decimal(protocolFee) / Decimal(feeDenominator))
Expand All @@ -100,6 +101,7 @@ def depositAtom(value: Decimal, totalAssets: Decimal, totalShares: Decimal) -> t

return (userSharesForTheAtom, totalSharesAtomVault, totalAssetsAtomVault, protocolVaultAssets)


def depositTriple(value: Decimal, totalAssets: Decimal, totalShares: Decimal, totalAssetsAtom: Decimal, totalSharesAtom: Decimal) -> tuple[Decimal, Decimal, Decimal, Decimal, Decimal, Decimal, Decimal]:
# Variables for triple
protocolFeeAmount = math.ceil(value * Decimal(protocolFee) / Decimal(feeDenominator))
Expand Down Expand Up @@ -139,7 +141,6 @@ def depositTriple(value: Decimal, totalAssets: Decimal, totalShares: Decimal, to
totalSharesAtomVault = userSharesForTheAtom

# Addresses
#zeroWalletShares = Decimal(2) * Decimal(minShare)
protocolVaultAssets = Decimal(protocolFeeAmount)

return (userSharesPositiveVault,
Expand All @@ -151,6 +152,25 @@ def depositTriple(value: Decimal, totalAssets: Decimal, totalShares: Decimal, to
protocolVaultAssets)


def redeemAtom(shares: Decimal, totalAssets: Decimal, totalShares: Decimal):
if (totalShares == 0):
userAssets = shares
else:
userAssets = math.floor((shares * totalAssets) / totalShares)

protocolFeeAmount = math.ceil(Decimal(userAssets) * Decimal(protocolFee) / Decimal(feeDenominator))
userAssetsAfterProtocolFees = Decimal(userAssets) - Decimal(protocolFeeAmount)

if (totalShares - shares == minShare):
exitFeeAmount = 0
else:
exitFeeAmount = math.ceil(userAssetsAfterProtocolFees * Decimal(exitFee) / Decimal(feeDenominator))

userAssetsAfterExitFees = userAssetsAfterProtocolFees - Decimal(exitFeeAmount)

return (userAssetsAfterExitFees, protocolFeeAmount, exitFeeAmount)


## ------------ Create Atom data ------------

print()
Expand Down Expand Up @@ -343,3 +363,40 @@ def depositTriple(value: Decimal, totalAssets: Decimal, totalShares: Decimal, to
protocolVaultAssets: {protocolVaultAssets2} \
}}) \
}}));".replace(" ", ''))


## ------------ Redeem Atom data ------------

print()
print("Redeem atom data")

for value in [
atomCost,
Decimal(atomCost) + Decimal(1),
Web3.to_wei(Decimal('1'), 'ether'),
Web3.to_wei(Decimal('10'), 'ether'),
Web3.to_wei(Decimal('100'), 'ether'),
Web3.to_wei(Decimal('1000'), 'ether'),
]:
(userShares, totalShares, totalAssets, atomWalletShares, protocolVaultAssets) = createAtom(value)

for _ in range(3):
(userSharesFromDeposit, totalShares, totalAssets, protocolVaultAssetsFromDeposit) = depositAtom(value, totalAssets, totalShares)

userShares += userSharesFromDeposit
protocolVaultAssets += protocolVaultAssetsFromDeposit

(userAssets, protocolFeeAmount, exitFeeAmount) = redeemAtom(userShares, totalAssets, totalShares)

totalRemainingShares = totalShares - userShares
totalRemainingAssets = totalAssets - userAssets - protocolFeeAmount
protocolVaultAssets += protocolFeeAmount

print(f"useCaseRedeemAtoms.push(UseCaseRedeemAtom({{ \
value: {value}, \
shares: {userShares}, \
assets: {userAssets}, \
totalRemainingShares: {totalRemainingShares}, \
totalRemainingAssets: {totalRemainingAssets}, \
protocolVaultAssets: {protocolVaultAssets} \
}}));".replace(" ", ''))
122 changes: 117 additions & 5 deletions test/unit/EthMultiVault/UseCases.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,18 @@ contract UseCasesTest is EthMultiVaultBase, EthMultiVaultHelpers {
UseCaseAtom obj;
}

struct UseCaseRedeemAtom {
uint256 value;
uint256 shares;
uint256 assets;
uint256 totalRemainingShares;
uint256 totalRemainingAssets;
uint256 protocolVaultAssets;
}

UseCaseAtom[] useCaseAtoms;
UseCaseTriple[] useCaseTriples;
UseCaseRedeemAtom[] useCaseRedeemAtoms;

function setUp() external {
_setUp();
Expand Down Expand Up @@ -228,6 +238,108 @@ contract UseCasesTest is EthMultiVaultBase, EthMultiVaultHelpers {
}
}

function testUseCasesRedeemAtom() external {
useCaseRedeemAtoms.push(
UseCaseRedeemAtom({
value: 300000000100000,
shares: 819530524365958,
assets: 830675569788504,
totalRemainingShares: 100000000100000,
totalRemainingAssets: 151492154481026,
protocolVaultAssets: 217832276130470
})
);
useCaseRedeemAtoms.push(
UseCaseRedeemAtom({
value: 300000000100001,
shares: 819530524365958,
assets: 830675569788504,
totalRemainingShares: 100000000100000,
totalRemainingAssets: 151492154481026,
protocolVaultAssets: 217832276130474
})
);
useCaseRedeemAtoms.push(
UseCaseRedeemAtom({
value: 1000000000000000000,
shares: 3748889220983980557,
assets: 3724095382864819517,
totalRemainingShares: 100000000100000,
totalRemainingAssets: 196110643367347144,
protocolVaultAssets: 79793973767833339
})
);
useCaseRedeemAtoms.push(
UseCaseRedeemAtom({
value: 10000000000000000000,
shares: 37491616096457688477,
assets: 37243515383249751406,
totalRemainingShares: 100000000100000,
totalRemainingAssets: 1960290642978322412,
protocolVaultAssets: 796193973771926182
})
);
useCaseRedeemAtoms.push(
UseCaseRedeemAtom({
value: 100000000000000000000,
shares: 374918884846505054817,
assets: 372437715383288241292,
totalRemainingShares: 100000000100000,
totalRemainingAssets: 19602090642939423277,
protocolVaultAssets: 7960193973772335431
})
);
useCaseRedeemAtoms.push(
UseCaseRedeemAtom({
value: 1000000000000000000000,
shares: 3749191572346509791407,
assets: 3724379715383292090248,
totalRemainingShares: 100000000100000,
totalRemainingAssets: 196020090642935533396,
protocolVaultAssets: 79600193973772376356
})
);

uint256 length = useCaseRedeemAtoms.length;
uint256 protocolVaultBalanceBefore;

for (uint256 i = 0; i < length; i++) {
UseCaseRedeemAtom storage u = useCaseRedeemAtoms[i];

vm.startPrank(rich, rich);

// 1 create atom
uint256 id = ethMultiVault.createAtom{value: u.value}(abi.encodePacked("atom", i));

// 3 deposits to the atom
for (uint256 j = 0; j < 3; j++) {
ethMultiVault.depositAtom{value: u.value}(rich, id);
}

uint256 shares = vaultBalanceOf(id, rich);

// 1 redeem total
uint256 assets = ethMultiVault.redeemAtom(shares, rich, id);

// atom values
uint256 sharesAfter = vaultBalanceOf(id, rich);
uint256 totalShares = vaultTotalShares(id);
uint256 totalAssets = vaultTotalAssets(id);
uint256 protocolVaultAssets = address(getProtocolVault()).balance;

assertEq(shares, u.shares);
assertEq(0, sharesAfter);
assertEq(assets, u.assets);
assertEq(totalShares, u.totalRemainingShares);
assertEq(totalAssets, u.totalRemainingAssets);
assertEq(protocolVaultAssets, u.protocolVaultAssets + protocolVaultBalanceBefore);

protocolVaultBalanceBefore = protocolVaultAssets;

vm.stopPrank();
}
}

function testUseCasesCreateTriple() external {
useCaseTriples.push(
UseCaseTriple({
Expand Down Expand Up @@ -448,12 +560,12 @@ contract UseCasesTest is EthMultiVaultBase, EthMultiVaultHelpers {

vm.startPrank(rich, rich);

// create atoms
// 3 create atoms
uint256 subjectId = ethMultiVault.createAtom{value: u.subject.value}(abi.encodePacked("subject", i));
uint256 predicateId = ethMultiVault.createAtom{value: u.predicate.value}(abi.encodePacked("predicate", i));
uint256 objectId = ethMultiVault.createAtom{value: u.obj.value}(abi.encodePacked("object", i));

// create triple
// 1 create triple
uint256 id = ethMultiVault.createTriple{value: u.value}(subjectId, predicateId, objectId);

// check subject atom values
Expand Down Expand Up @@ -716,15 +828,15 @@ contract UseCasesTest is EthMultiVaultBase, EthMultiVaultHelpers {

vm.startPrank(rich, rich);

// create atoms
// 3 create atoms
uint256 subjectId = ethMultiVault.createAtom{value: u.subject.value}(abi.encodePacked("subject", i));
uint256 predicateId = ethMultiVault.createAtom{value: u.predicate.value}(abi.encodePacked("predicate", i));
uint256 objectId = ethMultiVault.createAtom{value: u.obj.value}(abi.encodePacked("object", i));

// create triple
// 1 create triple
uint256 id = ethMultiVault.createTriple{value: u.value}(subjectId, predicateId, objectId);

// 3 deposits to the tripe
// 3 deposits to the triple
for (uint256 j = 0; j < 3; j++) {
ethMultiVault.depositTriple{value: u.value}(rich, id);
}
Expand Down

0 comments on commit c65bed1

Please sign in to comment.