Function: openPosition(OpenPositionRequest _request, Signature _signature)
This function can be used to open a position, long or short, according to the data passed in the _request argument.
Inputs
_requestControl: Unclear; this argument is validated and signed by an off-chain, out-of-scope component.
Constraints:
idmust not be already used.currencycould be anything except a base token.targetCurrencymust be a base token.downPaymentis not directly constrained by the smart contract.principalmust be at most the vault principal balance and is also checked to be no more than the computed maximum principal amount to prevent overleveraging.minTargetAmountis not directly constrained and is used to implement antislippage checks.expirationmust be after the currentblock.timestamp.feeis not constrained.functionCallDataListis not constrained.
Impact: Specifies all the parameters of the position.
_signatureControl: Arbitrary.
Constraints: Must be a valid signature of
_requestfrom the contract owner.Impact: Signature authorizing the operation.
Branches and code coverage
Intended branches
After performing validation of the
_requestargument, it executes the calls specified infunctionCallDataList, which are intended to grant approval and call Uniswap to perform the needed trade, selling the shorted principal asset for the collateral. After checking the received collateral amount and the principal, the hash identifying the position is recorded in storage.
Negative behavior
Reverts if the signature is invalid.
Reverts if the position ID is already used.
Reverts if
functionCallDataListis empty.Reverts if the request is expired.
Reverts if the
currencyis a base token.Reverts if the
targetCurrencyis not a base token.Reverts if receiving the payment fails (for raw ETH).
Reverts if receiving the payment fails (for WETH / other ERC-20).
Reverts if the requested principal is more than the available balance.
Reverts if the received collateral is less than the minumum specified in the request.
Reverts if the requested principal would overleverage the user.
Function call analysis
this._validateOpenPositionRequest(_request, _signature) -> PerpUtils.receivePayment(this.isLongPool ? _request.currency : _request.targetCurrency, _request.downPayment + _request.fee, this.addressProvider.getWethAddress(), msg.sender)What is controllable?
targetCurrencyand amount (to some extent).If the return value is controllable, how is it used and how can it go wrong? Not used.
What happens if it reverts, reenters or does other unusual control flow? Reentrancy is prevented via
nonReentrantmodifier (apart from admin-only functions).
principalToken.balanceOf(address(this))What is controllable?
principalTokenis signed, but it must be validated by the off-chain component.If the return value is controllable, how is it used and how can it go wrong? Used as the balance of the principal token before the swap.
What happens if it reverts, reenters or does other unusual control flow? Reentrancy is prevented via
nonReentrantmodifier (apart from admin-only functions).
collateralToken.balanceOf(address(this))What is controllable?
collateralTokenis signed, but it must be validated by the off-chain component.If the return value is controllable, how is it used and how can it go wrong? Used as the collateral balance before the swap.
What happens if it reverts, reenters or does other unusual control flow? Reentrancy is prevented via
nonReentrantmodifier (apart from admin-only functions).
PerpUtils.executeFunctions(_request.functionCallDataList)What is controllable? Nothing directly — argument provided by the off-chain component.
If the return value is controllable, how is it used and how can it go wrong? Not used.
What happens if it reverts, reenters or does other unusual control flow? Reentrancy is prevented via
nonReentrantmodifier (apart from admin-only functions).
collateralToken.balanceOf(address(this))What is controllable? As above,
collateralTokenis signed, but it must be validated by the off-chain component.If the return value is controllable, how is it used and how can it go wrong? Used as the collateral balance after the swap.
What happens if it reverts, reenters or does other unusual control flow? Reentrancy is prevented via
nonReentrantmodifier (apart from admin-only functions).
this.addressProvider.getDebtController().computeMaxPrincipal(_request.targetCurrency, _request.currency, swappedDownPaymentAmount)What is controllable?
targetCurrencyandcurrency, to the extent permitted by the off-chain component. They are currently unused.If the return value is controllable, how is it used and how can it go wrong? Used to limit the maximum amount of principal the user can request.
What happens if it reverts, reenters or does other unusual control flow? The caller cannot cause the call to reenter or revert.
principalToken.balanceOf(address(this))What is controllable?
principalTokenis signed and validated by the off-chain component.If the return value is controllable, how is it used and how can it go wrong? Used to determine the amount of principal gained from the swap.
What happens if it reverts, reenters or does other unusual control flow? Reentrancy is prevented via
nonReentrantmodifier (apart from admin-only functions).