# VaultZapper

## VaultZapper

[Git Source](https://github.com/AmphorProtocol/asynchronous-synthetic-private/blob/c4f7a9b8f3d3d9aba0e43eaae38ef9b556023b0e/src/VaultZapper.sol)

**Inherits:** Ownable2Step, Pausable

### State Variables

#### authorizedVaults

The `authorizedVaults` mapping is used to check if a vault is authorized to interact with the `VaultZapper` contract.

*The `SafeERC20` lib is only used for `safeTransfer`, `safeTransferFrom` and `forceApprove` operations.*

*The `Address` lib is only used for `sendValue` operations.*

```solidity
mapping(IERC4626 vault => bool isAuthorized) public authorizedVaults;
```

#### authorizedRouters

The `authorizedRouters` mapping is used to check if a router is authorized to interact with the `VaultZapper` contract.

```solidity
mapping(address routerAddress => bool isAuthorized) public authorizedRouters;
```

### Functions

#### onlyAllowedRouter

*The `onlyAllowedRouter` modifier is used to check if a router is authorized to interact with the `VaultZapper` contract.*

```solidity
modifier onlyAllowedRouter(address router);
```

#### onlyAllowedVault

*The `onlyAllowedVault` modifier is used to check if a vault is authorized to interact with the `VaultZapper` contract.*

```solidity
modifier onlyAllowedVault(IERC4626 vault);
```

#### constructor

```solidity
constructor() Ownable(_msgSender());
```

#### withdrawToken

*The `withdrawToken` function is used to withdraw tokens from the `VaultZapper` contract.*

```solidity
function withdrawToken(IERC20 token) external onlyOwner;
```

#### withdrawNativeToken

*The `withdrawNativeToken` function is used to withdraw native tokens from the `VaultZapper` contract.*

```solidity
function withdrawNativeToken() external onlyOwner;
```

#### pause

*The `pause` function is used to pause the `VaultZapper` contract.*

```solidity
function pause() external onlyOwner;
```

#### unpause

*The `unpause` function is used to unpause the `VaultZapper` contract.*

```solidity
function unpause() external onlyOwner;
```

#### approveTokenForRouter

*The `approveTokenForRouter` function is used to approve a token for a router.*

```solidity
function approveTokenForRouter(
    IERC20 token,
    address router
)
    public
    onlyOwner
    onlyAllowedRouter(router);
```

#### toggleRouterAuthorization

*The `toggleRouterAuthorization` function is used to toggle the authorization of a router.*

```solidity
function toggleRouterAuthorization(address router) public onlyOwner;
```

#### toggleVaultAuthorization

*The `toggleVaultAuthorization` function is used to toggle the authorization of a vault.*

```solidity
function toggleVaultAuthorization(IERC7540 vault) public onlyOwner;
```

#### \_zapIn

*The `_zapIn` function is used to zap in assets into a vault.*

```solidity
function _zapIn(
    IERC20 tokenIn,
    address router,
    uint256 amount,
    bytes calldata data
)
    internal;
```

#### \_transferTokenInAndApprove

*The `_transferTokenInAndApprove` function is used to transfer tokens into the `VaultZapper` contract and approve them for a router.*

```solidity
function _transferTokenInAndApprove(
    address router,
    IERC20 tokenIn,
    uint256 amount
)
    internal;
```

#### zapAndDeposit

*The `zapAndDeposit` function is used to zap in and deposit assets into a vault.*

```solidity
function zapAndDeposit(
    IERC20 tokenIn,
    IERC4626 vault,
    address router,
    uint256 amount,
    bytes calldata data
)
    public
    payable
    onlyAllowedRouter(router)
    onlyAllowedVault(vault)
    whenNotPaused
    returns (uint256);
```

#### zapAndRequestDeposit

*The `zapAndRequestDeposit` function is used to zap in and request a deposit of assets into a vault.*

```solidity
function zapAndRequestDeposit(
    IERC20 tokenIn,
    IERC7540 vault,
    address router,
    uint256 amountIn,
    bytes calldata data,
    bytes calldata swapData
)
    public
    payable
    onlyAllowedRouter(router)
    onlyAllowedVault(vault)
    whenNotPaused;
```

#### zapAndClaimAndRequestDeposit

*The `zapAndClaimAndRequestDeposit` function is used to zap in, claim and request a deposit of assets into a vault.*

```solidity
function zapAndClaimAndRequestDeposit(
    IERC20 tokenIn,
    AsyncSynthVault vault,
    address router,
    uint256 amountIn,
    bytes calldata data,
    bytes calldata swapData
)
    public
    payable
    onlyAllowedRouter(router)
    onlyAllowedVault(vault)
    whenNotPaused;
```

#### zapAndDepositWithPermit

*The `zapAndDepositWithPermit` function is used to zap in and deposit assets into a vault with a permit.*

```solidity
function zapAndDepositWithPermit(
    IERC20 tokenIn,
    IERC4626 vault,
    address router,
    uint256 amount,
    bytes calldata swapData,
    PermitParams calldata permitParams
)
    public
    returns (uint256);
```

#### zapAndRequestDepositWithPermit

*The `zapAndRequestDepositWithPermit` function is used to zap in and request a deposit of assets into a vault with a permit.*

```solidity
function zapAndRequestDepositWithPermit(
    IERC20 tokenIn,
    IERC7540 vault,
    address router,
    uint256 amount,
    bytes calldata data,
    bytes calldata swapData,
    PermitParams calldata permitParams
)
    public;
```

#### zapAndClaimAndRequestDepositWithPermit

*The `zapAndClaimAndRequestDepositWithPermit` function is used to zap in, claim and request a deposit of assets into a vault with a permit.*

```solidity
function zapAndClaimAndRequestDepositWithPermit(
    IERC20 tokenIn,
    AsyncSynthVault vault,
    address router,
    uint256 amount,
    bytes calldata data,
    bytes calldata swapData,
    PermitParams calldata permitParams
)
    public;
```

#### \_executeZap

*The `_executeZap` function is used to execute a zap.*

```solidity
function _executeZap(
    address target,
    bytes memory data
)
    internal
    returns (bytes memory response);
```

#### \_executePermit

*The `_executePermit` function is used to execute a permit.*

```solidity
function _executePermit(
    IERC20 token,
    address owner,
    address spender,
    PermitParams calldata permitParams
)
    internal;
```

### Events

#### ZapAndRequestDeposit

*The `ZapAndDeposit` event is emitted when a user zaps in and deposits assets into a vault.*

```solidity
event ZapAndRequestDeposit(
    IERC7540 indexed vault,
    address indexed router,
    IERC20 tokenIn,
    uint256 amount
);
```

#### ZapAndDeposit

*The `ZapAndDeposit` event is emitted when a user zaps in and deposits assets into a vault.*

```solidity
event ZapAndDeposit(
    IERC4626 indexed vault,
    address indexed router,
    IERC20 tokenIn,
    uint256 amount,
    uint256 shares
);
```

#### ClaimRedeemAndZap

*The `ClaimRedeemAndZap` event is emitted when a user claims, redeems and zaps assets into a vault.*

```solidity
event ClaimRedeemAndZap(
    IERC7540 indexed vault,
    address indexed router,
    uint256 shares,
    uint256 assets
);
```

#### RouterApproved

*The `RouterApproved` event is emitted when a router is approved to interact with a token.*

```solidity
event RouterApproved(address indexed router, IERC20 indexed token);
```

#### RouterAuthorized

*The `RouterAuthorized` event is emitted when a router is authorized to interact with the `VaultZapper` contract.*

```solidity
event RouterAuthorized(address indexed router, bool allowed);
```

#### VaultAuthorized

*The `VaultAuthorized` event is emitted when a vault is authorized to interact with the `VaultZapper` contract.*

```solidity
event VaultAuthorized(IERC4626 indexed vault, bool allowed);
```

### Errors

#### NotRouter

*The `NotRouter` error is emitted when a router is not authorized to interact with the `VaultZapper` contract.*

```solidity
error NotRouter(address router);
```

#### NotVault

*The `NotVault` error is emitted when a vault is not authorized to interact with the `VaultZapper` contract.*

```solidity
error NotVault(IERC4626 vault);
```

#### SwapFailed

*The `SwapFailed` error is emitted when a swap fails.*

```solidity
error SwapFailed(string reason);
```

#### InconsistantSwapData

*The `InconsistantSwapData` error is emitted when the swap data is inconsistant.*

```solidity
error InconsistantSwapData(
    uint256 expectedTokenInBalance, uint256 actualTokenInBalance
);
```

#### NotEnoughSharesMinted

*The `NotEnoughSharesMinted` error is emitted when the amount of shares minted is not enough.*

```solidity
error NotEnoughSharesMinted(uint256 sharesMinted, uint256 minSharesMinted);
```

#### NotEnoughUnderlying

*The `NotEnoughUnderlying` error is emitted when the amount of underlying assets is not enough.*

```solidity
error NotEnoughUnderlying(
    uint256 previewedUnderlying, uint256 withdrawedUnderlying
);
```

#### NullMinShares

*The `NullMinShares` error is emitted when the minimum amount of shares to mint is null.*

```solidity
error NullMinShares();
```
