Skip to main content

PWN Vault

1. Summary​

Loan contracts in the PWN Protocol inherit the PWNVault.sol contract for transferring and managing assets. Enables usage of PWN pool adapters to utilise assets in other contracts. This is not a standalone contract.

3. Contract details​

  • PWNVault.sol is written in Solidity version 0.8.16

Features​

  • Transferring assets
  • Utilising assets from external pools
  • Set Vault allowance for an asset

Inherited contracts, implemented Interfaces and ERCs​

Internal Functions​

_pull

Overview​

Takes a supplied asset and pulls it into the vault from the origin.

This function assumes a prior token approval was made to the vault address.

This function takes two arguments supplied by the caller:

  • MultiToken.Assetasset - The transferred asset (see MultiToken)
  • address indexedorigin

Implementation​

function _pull(MultiToken.Asset memory asset, address origin) internal {
uint256 originalBalance = asset.balanceOf(address(this));

asset.transferAssetFrom(origin, address(this));
_checkTransfer(asset, originalBalance, address(this));

emit VaultPull(asset, origin);
}
_push

Overview​

Pushes a supplied asset from the vault to the beneficiary.

This function takes two arguments supplied by the caller:

  • MultiToken.Assetasset - The transferred asset (see MultiToken)
  • address indexedbeneficiary

Implementation​

function _push(MultiToken.Asset memory asset, address beneficiary) internal {
uint256 originalBalance = asset.balanceOf(beneficiary);

asset.safeTransferAssetFrom(address(this), beneficiary);
_checkTransfer(asset, originalBalance, beneficiary);

emit VaultPush(asset, beneficiary);
}
_pushFrom

Overview​

Pushes a supplied asset from the origin to the beneficiary.

This function assumes a prior token approval was made to the vault address.

This function takes three arguments supplied by the caller:

  • MultiToken.Assetasset - The transferred asset (see MultiToken)
  • address indexedorigin
  • address indexedbeneficiary

Implementation​

function _pushFrom(MultiToken.Asset memory asset, address origin, address beneficiary) internal {
uint256 originalBalance = asset.balanceOf(beneficiary);

asset.safeTransferAssetFrom(origin, beneficiary);
_checkTransfer(asset, originalBalance, beneficiary);

emit VaultPushFrom(asset, origin, beneficiary);
}
_tryPermit

Overview​

Try to execute a permit for an ERC20 token. If the permit execution fails, the function will not revert.

This function takes one argument:

  • Permit memorypermit - The permit data

Implementation​

function _tryPermit(Permit memory permit) internal {
if (permit.asset != address(0)) {
try IERC20Permit(permit.asset).permit({
owner: permit.owner,
spender: address(this),
value: permit.amount,
deadline: permit.deadline,
v: permit.v,
r: permit.r,
s: permit.s
}) {} catch {
// Note: Permit execution can be frontrun, so we don't revert on failure.
}
}
}
_withdrawFromPool

Overview​

This function withdraws an asset from a pool to a owner.

This function takes four arguments:

  • MultiToken.Asset memoryasset - The withdrawn asset (see MultiToken)
  • IPoolAdapterpoolAdapter - An address of a pool adapter
  • addresspool - An address of a pool
  • addressowner - An address on which behalf the assets are withdrawn

Implementation​

function _withdrawFromPool(MultiToken.Asset memory asset, IPoolAdapter poolAdapter, address pool, address owner) internal {
uint256 originalBalance = asset.balanceOf(owner);

poolAdapter.withdraw(pool, owner, asset.assetAddress, asset.amount);
_checkTransfer(asset, originalBalance, owner, true);

emit PoolWithdraw(asset, address(poolAdapter), pool, owner);
}
_supplyToPool

Overview​

This function supplies an asset from an owner to a pool.

This function takes four arguments:

  • MultiToken.Asset memoryasset - The supplied asset (see MultiToken)
  • IPoolAdapterpoolAdapter - An address of a pool adapter
  • addresspool - An address of a pool
  • addressowner - An address on which behalf the assets are supplied

Implementation​

function _supplyToPool(MultiToken.Asset memory asset, IPoolAdapter poolAdapter, address pool, address owner) internal {
uint256 originalBalance = asset.balanceOf(address(this));

asset.transferAssetFrom(address(this), address(poolAdapter));
poolAdapter.supply(pool, owner, asset.assetAddress, asset.amount);
_checkTransfer(asset, originalBalance, address(this), false);

// Note: Assuming pool will revert supply transaction if it fails.

emit PoolSupply(asset, address(poolAdapter), pool, owner);
}
_checkTransfer

Overview​

Function to verify a complete transfer.

This function takes four arguments:

  • MultiToken.Asset memoryasset - The asset to check (see MultiToken)
  • uint256originalBalance - The original balance
  • addresscheckedAddress - The address to check
  • boolcheckIncreasingBalance - A flag to set the check for either balance decrease or increase

Implementation​

function _checkTransfer(
MultiToken.Asset memory asset,
uint256 originalBalance,
address checkedAddress,
bool checkIncreasingBalance
) private view {
uint256 expectedBalance = checkIncreasingBalance
? originalBalance + asset.getTransferAmount()
: originalBalance - asset.getTransferAmount();

if (expectedBalance != asset.balanceOf(checkedAddress)) {
revert IncompleteTransfer();
}
}

Events​

The PWN Vault contract defines four events and two errors.

event VaultPull(MultiToken.Asset asset, address indexed origin);
event VaultPush(MultiToken.Asset asset, address indexed beneficiary);
event VaultPushFrom(MultiToken.Asset asset, address indexed origin, address indexed beneficiary);
event PoolWithdraw(MultiToken.Asset asset, address indexed poolAdapter, address indexed pool, address indexed owner);
event PoolSupply(MultiToken.Asset asset, address indexed poolAdapter, address indexed pool, address indexed owner);
VaultPull

VaultPull event is emitted when a transfer happens from the origin to the vault.

This event has two parameters:

  • MultiToken.Assetasset - The transferred asset (see MultiToken)
  • address indexedorigin
VaultPush

VaultPush event is emitted when a transfer happens from the vault to the beneficiary.

This event has two parameters:

  • MultiToken.Assetasset - The transferred asset (see MultiToken)
  • address indexedbeneficiary
VaultPushFrom

VaultPushFrom event is emitted when a transfer happens from the origin to the beneficiary.

This event has three parameters:

  • MultiToken.Assetasset - The transferred asset (see MultiToken)
  • address indexedorigin
  • address indexedbeneficiary
PoolWithdraw

PoolWithdraw event is emitted when an asset is withdrawn from a pool to an owner address.

This event has four parameters:

  • MultiToken.Assetasset - The withdrawn asset (see MultiToken)
  • address indexedpoolAdapter
  • address indexedpool
  • address indexedowner
PoolSupply

PoolSupply event is emitted when an asset is supplied to a pool from a vault.

This event has four parameters:

  • MultiToken.Assetasset - The supplied asset (see MultiToken)
  • address indexedpoolAdapter
  • address indexedpool
  • address indexedowner

Errors​

error UnsupportedTransferFunction();
error IncompleteTransfer();
UnsupportedTransferFunction

UnsupportedTransferFunction error is thrown when the Vault receives an asset that is not transferred by the Vault itself.

IncompleteTransfer

IncompleteTransfer error is thrown when an asset transfer is incomplete.