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.
2. Important links
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 indexedoriginaddress 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 adapteraddresspool- An address of a pooladdressowner- 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 adapteraddresspool- An address of a pooladdressowner- 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 balanceaddresscheckedAddress- The address to checkboolcheckIncreasingBalance- 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 indexedoriginaddress 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 indexedpoolAdapteraddress indexedpooladdress 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 indexedpoolAdapteraddress indexedpooladdress 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.