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
_request
Control: Unclear; this argument is validated and signed by an off-chain, out-of-scope component.
Constraints:
id
must not be already used.currency
could be anything except a base token.targetCurrency
must be a base token.downPayment
is not directly constrained by the smart contract.principal
must be at most the vault principal balance and is also checked to be no more than the computed maximum principal amount to prevent overleveraging.minTargetAmount
is not directly constrained and is used to implement antislippage checks.expiration
must be after the currentblock.timestamp
.fee
is not constrained.functionCallDataList
is not constrained.
Impact: Specifies all the parameters of the position.
_signature
Control: Arbitrary.
Constraints: Must be a valid signature of
_request
from the contract owner.Impact: Signature authorizing the operation.
Branches and code coverage
Intended branches
After performing validation of the
_request
argument, 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
functionCallDataList
is empty.Reverts if the request is expired.
Reverts if the
currency
is a base token.Reverts if the
targetCurrency
is 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?
targetCurrency
and 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
nonReentrant
modifier (apart from admin-only functions).
principalToken.balanceOf(address(this))
What is controllable?
principalToken
is 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
nonReentrant
modifier (apart from admin-only functions).
collateralToken.balanceOf(address(this))
What is controllable?
collateralToken
is 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
nonReentrant
modifier (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
nonReentrant
modifier (apart from admin-only functions).
collateralToken.balanceOf(address(this))
What is controllable? As above,
collateralToken
is 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
nonReentrant
modifier (apart from admin-only functions).
this.addressProvider.getDebtController().computeMaxPrincipal(_request.targetCurrency, _request.currency, swappedDownPaymentAmount)
What is controllable?
targetCurrency
andcurrency
, 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?
principalToken
is 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
nonReentrant
modifier (apart from admin-only functions).