Lack of validation
The following outlines areas in the scoped contracts that lack validation.
The
constructorof multiple contracts lacks essential input-parameter validation, such as verifying that the addresses of the contracts are not zero addresses. This absence of validation could lead to the deployment of contracts with invalid configurations. In some contracts, the owner has the flexibility to update global variables. However, in thereserveTokencontract, for example, thereserveTokenaddress is declared as immutable, making it unchangeable after deployment.
The
investWithToken()andexitToToken()functions of the OrigamiInvestmentVault contract utilizequoteDatagenerated by theinvestQuote()andexitQuote()functions, correspondingly. These functions generateInvestQuoteDataorExitQuoteDatadata, which include theunderlyingInvestmentQuoteDatafield. It is assumed that this field duplicates and encodes all information present in other fields of thequoteData. For example, thequoteData.underlyingInvestmentQuoteData.investmentTokenAmountshould be identical toquoteData.investmentTokenAmount, and so forth. However, theinvestWithToken()andexitToToken()functions do not explicitly validate these data duplications, which poses potential security risks.
For example, it is assumed that the reserveToken contract should utilize all tokens approved by the OrigamiInvestmentVault contract during the investment process. Therefore, if users try to use different token addresses for underlyingInvestmentQuoteData.fromToken and quoteData.fromToken calling the investWithToken() function, the transaction should revert because reserveToken.investWithToken() will not be able to transfer invested tokens from the OrigamiInvestmentVault contract. But if the quoteData is improperly prepared by a user, it can lead to the underutilization of approved tokens, and the reserveToken contract will have the excessive approval from the OrigamiInvestmentVault for the invested tokens.
This scenario presents an opportunity for exploitation by a malicious user. The user could leverage the excess tokens to conduct investments using their own quoteData, where the fields quoteData.underlyingInvestmentQuoteData.fromToken and quoteData.fromToken differ. This could result in the investment of arbitrary tokens into the OrigamiInvestmentVault contract, while approved tokens will be utilized in the reserveToken contract.
The
reservesVestingDurationfrom the RepricingToken contract determines how long in seconds the new reserve's funds will be under vesting. But the contract does not specify the maximum value to which thereservesVestingDurationcan be limited. Therefore, a user with an access to thesetReservesVestingDurationfunction can update this value to any up to themax(uint256).
Remediation
This issue has been acknowledged by TempleDAO, and a fix was implemented in commit 46423d0b↗.