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

Preliminary Report fixes #158

Merged
merged 30 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1057387
fix: F-2024-6721 - added missing storage gap
Krishnakumarskr Oct 23, 2024
1ec48d6
fix: F-2024-6699 - changed the params order
Krishnakumarskr Oct 23, 2024
609d9b9
chore: Improve LiquidContinuousMultiTokenVault testing and branch cov…
lucasia Oct 23, 2024
2cbf196
chore: Improve LiquidContinuousMultiTokenVault testing and branch cov…
lucasia Oct 23, 2024
bcb1b71
chore: Improve LiquidContinuousMultiTokenVault testing
lucasia Oct 23, 2024
3c46905
chore: Improve LiquidContinuousMultiTokenVault testing - add convertT…
lucasia Oct 23, 2024
047ee0a
chore: Introduce support for different user accounts in MultiTokenVau…
lucasia Oct 24, 2024
e6d64fe
fix: Correct account verification (msgSender, owner, controller). Cl…
lucasia Oct 24, 2024
c3d58e0
fix: Correct account verification (msgSender, owner, controller). Cl…
lucasia Oct 24, 2024
6c28ce7
fix: F-2024-6693 revert if deposit is fractional
Krishnakumarskr Oct 25, 2024
8593697
:white_check_mark: Add Test Cases
nawar-hisso Oct 25, 2024
9117a32
:fire: Remove Comments
nawar-hisso Oct 25, 2024
227e4e3
chore: Utilize TestUsers in more tests. Remove duplicate loadTest code
lucasia Oct 25, 2024
769fee7
Tweaked to allow setting of a custom `maxDeposit` while also accessin…
jplodge-pro Oct 28, 2024
ef8d68b
Added the Branch Coverage option to the `genhtml` invocation.
jplodge-pro Oct 28, 2024
8288924
Added a test case for Max Deposit being exceeded on deposit.
jplodge-pro Oct 28, 2024
065ac0b
pulled latest changes
Krishnakumarskr Oct 28, 2024
48ec6c2
Merge branch 'preliminary-report-fixes' of https://github.com/credbul…
Krishnakumarskr Oct 28, 2024
9339f84
added test cases
Krishnakumarskr Oct 28, 2024
323511c
:twisted_rightwards_arrows: Merge
nawar-hisso Oct 28, 2024
0341366
:fire: Remove Unused Code
nawar-hisso Oct 28, 2024
aa503e5
Merge pull request #165 from credbull/optimize-multi-token-vault-test…
nawar-hisso Oct 28, 2024
4ad6226
test case for fractional redeem
Krishnakumarskr Oct 28, 2024
c616d7d
reverted fix for fractional shares and added tests
Krishnakumarskr Oct 28, 2024
a65e1e2
Merge branch 'preliminary-report-fixes' of https://github.com/credbul…
Krishnakumarskr Oct 28, 2024
0d24bb0
fix: Reduce LiquidStones minimum threshold for shares to assets conve…
lucasia Oct 28, 2024
ca9348c
chore: Fix minor linting issue
lucasia Oct 28, 2024
0258628
chore: Add test for Deposit and Redeem at cut-off times
lucasia Oct 28, 2024
c782b73
fix: Correct LiquidStone product to return 0 returns when depositing …
lucasia Oct 29, 2024
cce3896
F-2024-6700 - TimelockAsyncUnlock (#164)
ChaiSomsri96 Oct 29, 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
2 changes: 1 addition & 1 deletion packages/contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"dev": "yarn rm-dbdata && anvil --config-out localhost.json & make deploy-local",
"build": "forge build && yarn gen-types",
"test": "forge test",
"coverage": "forge coverage --report lcov && genhtml lcov.info -o out/test-reports/coverage --ignore-errors inconsistent",
"coverage": "forge coverage --report lcov && genhtml lcov.info --branch-coverage -o out/test-reports/coverage --ignore-errors inconsistent",
"format": "forge fmt && prettier './script/**/*.js' --write",
"lint": "forge fmt && eslint --fix --ignore-path .gitignore && yarn solhint './*(test|src)/**/*.sol'",
"db-check": "tsc && node ./script/utils/checkDb.js",
Expand Down
1 change: 1 addition & 0 deletions packages/contracts/src/token/ERC1155/MultiTokenVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ abstract contract MultiTokenVault is
error MultiTokenVault__CallerMissingApprovalForAll(address operator, address owner);
error MultiTokenVault__RedeemBeforeDeposit(address owner, uint256 depositPeriod, uint256 redeemPeriod);
error MultiTokenVault__InvalidArrayLength(uint256 depositPeriodsLength, uint256 sharesLength);
error MultiTokenVault__FractionalSharesNotAllowed();

constructor() {
_disableInitializers();
Expand Down
7 changes: 7 additions & 0 deletions packages/contracts/src/yield/CalcInterestMetadata.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,11 @@ abstract contract CalcInterestMetadata is Initializable, ICalcInterestMetadata {
function scale() public view virtual returns (uint256 scale_) {
return SCALE;
}

/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}
70 changes: 51 additions & 19 deletions packages/contracts/src/yield/LiquidContinuousMultiTokenVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ contract LiquidContinuousMultiTokenVault is

error LiquidContinuousMultiTokenVault__InvalidFrequency(uint256 frequency);
error LiquidContinuousMultiTokenVault__InvalidAuthAddress(string authName, address authAddress);
error LiquidContinuousMultiTokenVault__ControllerMismatch(address sender, address controller);
error LiquidContinuousMultiTokenVault__ControllerNotSender(address sender, address controller);
error LiquidContinuousMultiTokenVault__UnAuthorized(address sender, address authorizedOwner);
error LiquidContinuousMultiTokenVault__AmountMismatch(uint256 amount1, uint256 amount2);
error LiquidContinuousMultiTokenVault__UnlockPeriodMismatch(uint256 unlockPeriod1, uint256 unlockPeriod2);
error LiquidContinuousMultiTokenVault__InvalidComponentTokenAmount(
Expand Down Expand Up @@ -179,11 +180,12 @@ contract LiquidContinuousMultiTokenVault is
* @param owner Source of the assets to deposit
* @return requestId_ Discriminator between non-fungible requests
*/
function requestDeposit(uint256 assets, address controller, address owner) public returns (uint256 requestId_) {
if (controller != _msgSender()) {
revert LiquidContinuousMultiTokenVault__ControllerMismatch(_msgSender(), controller);
}

function requestDeposit(uint256 assets, address controller, address owner)
public
onlyAuthorized(owner)
onlyController(controller)
returns (uint256 requestId_)
{
uint256 requestId = ZERO_REQUEST_ID; // requests and requestIds not used in buys.

deposit(assets, owner, controller);
Expand All @@ -196,11 +198,11 @@ contract LiquidContinuousMultiTokenVault is
* @param assets Amount of `asset` that was deposited by `requestDeposit`
* @param receiver Address to receive the shares
*/
function deposit(uint256 assets, address receiver, address controller) public returns (uint256 shares_) {
if (controller != _msgSender()) {
revert LiquidContinuousMultiTokenVault__ControllerMismatch(_msgSender(), controller);
}

function deposit(uint256 assets, address receiver, address controller)
public
onlyController(controller)
returns (uint256 shares_)
{
uint256 shares = deposit(assets, receiver);
emit Deposit(controller, receiver, assets, shares);
return shares;
Expand All @@ -212,42 +214,49 @@ contract LiquidContinuousMultiTokenVault is
* @param owner Source of the shares to redeem
* @return requestId_ Discriminator between non-fungible requests
*/
function requestRedeem(uint256 shares, address, /* controller */ address owner)
function requestRedeem(uint256 shares, address controller, address owner)
public
onlyAuthorized(owner)
onlyController(controller)
returns (uint256 requestId_)
{
// using optimize() variant in case "shares" represents the IComponent "principal + yield" which is our "assets".
(uint256[] memory depositPeriods, uint256[] memory sharesAtPeriods) =
_redeemOptimizer.optimize(this, owner, shares, shares, minUnlockPeriod());

uint256 requestId = requestUnlock(_msgSender(), depositPeriods, sharesAtPeriods);
emit RedeemRequest(_msgSender(), owner, requestId, _msgSender(), shares);
uint256 requestId = requestUnlock(owner, depositPeriods, sharesAtPeriods);
emit RedeemRequest(controller, owner, requestId, _msgSender(), shares);
return requestId;
}

/**
* @notice Fulfill a request to redeem assets by transferring assets to the receiver
* @param shares Amount of shares that was redeemed by `requestRedeem`
* @param receiver Address to receive the assets
* @dev controller will only have tokens to redeem if they are also the owner
*/
function redeem(uint256 shares, address receiver, address /* controller */ ) public returns (uint256 assets) {
function redeem(uint256 shares, address receiver, address controller)
public
onlyController(controller)
returns (uint256 assets)
{
uint256 requestId = currentPeriod(); // requestId = redeemPeriod, and redeem can only be called where redeemPeriod = currentPeriod()

uint256 unlockRequestedAmount = unlockRequestAmount(receiver, requestId);
uint256 unlockRequestedAmount = unlockRequestAmount(controller, requestId);
if (shares != unlockRequestedAmount) {
revert LiquidContinuousMultiTokenVault__InvalidComponentTokenAmount(shares, unlockRequestedAmount);
}

(uint256[] memory depositPeriods, uint256[] memory sharesAtPeriods) = unlock(receiver, requestId); // unlockPeriod = redeemPeriod
(uint256[] memory depositPeriods, uint256[] memory sharesAtPeriods) = unlock(controller, requestId); // unlockPeriod = redeemPeriod

uint256 totalAssetsRedeemed = 0;

for (uint256 i = 0; i < depositPeriods.length; ++i) {
totalAssetsRedeemed += _redeemForDepositPeriodAfterUnlock(
sharesAtPeriods[i], receiver, _msgSender(), depositPeriods[i], requestId
sharesAtPeriods[i], receiver, controller, depositPeriods[i], requestId
);
}
emit Withdraw(_msgSender(), receiver, _msgSender(), totalAssetsRedeemed, shares);
emit Withdraw(_msgSender(), receiver, controller, totalAssetsRedeemed, shares);
return totalAssetsRedeemed;
}

Expand Down Expand Up @@ -393,6 +402,13 @@ contract LiquidContinuousMultiTokenVault is
return balanceOf(account, depositPeriod);
}

/// @inheritdoc TimelockAsyncUnlock
function _authorizeCaller(address caller, address owner) internal virtual override {
if (caller != owner && !isApprovedForAll(owner, caller)) {
revert LiquidContinuousMultiTokenVault__UnAuthorized(caller, owner);
}
}

// ===================== TripleRateContext =====================

/// @inheritdoc TripleRateContext
Expand Down Expand Up @@ -458,6 +474,22 @@ contract LiquidContinuousMultiTokenVault is

// ===================== Utility =====================

// @dev ensure caller is permitted to act on the owner's tokens
modifier onlyAuthorized(address owner) {
_authorizeCaller(_msgSender(), owner);
_;
}

// @dev ensure the controller is the caller
modifier onlyController(address controller) {
address caller = _msgSender();

if (caller != controller) {
revert LiquidContinuousMultiTokenVault__ControllerNotSender(caller, controller);
}
_;
}

function pause() public onlyRole(OPERATOR_ROLE) {
_pause();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ contract TripleRateYieldStrategy is AbstractYieldStrategy {
ITripleRateContext context = ITripleRateContext(contextContract);

return CalcSimpleInterest.calcPriceFromInterest(
numPeriodsElapsed, context.rateScaled(), context.frequency(), context.scale()
context.rateScaled(), numPeriodsElapsed, context.frequency(), context.scale()
);
}

Expand Down
Loading