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 one argument:

  • 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.

Last updated