# LibAsset

This contract defines a library called LibAsset which provides utility functions for handling assets, particularly focusing on native assets like Ether. The library includes several custom error types for handling various failure scenarios such as AssetNotReceived, ApprovalFailed, TransferFromFailed, TransferFailed, PermitFailed, FailedWrap, and FailedUnwrap. The isNative function checks if a given address represents a native asset (Ether) by comparing it to a constant NATIVE\_ASSETID, which is set to the zero address. The wrap function is designed to wrap a specified asset by using inline assembly to prepare a call to the asset’s contract. If the wrapping operation fails, it reverts with a FailedWrap error. Similarly, the unwrap function unwraps a specified asset, also using inline assembly to prepare the call and reverting with a FailedUnwrap error if the operation fails. Lastly, the getBalance function retrieves the balance of the current contract for a given asset by calling another internal function getBalanceOf.

<table data-full-width="false"><thead><tr><th width="210">Function Name</th><th>Description (Business Logic)</th></tr></thead><tbody><tr><td><mark style="color:red;"><strong>getBalanceOf</strong></mark> </td><td>The <mark style="color:red;"><strong>getBalanceOf</strong></mark> function retrieves the balance of a specified asset for a target address. It uses inline assembly to handle both native assets (Ether) and other ERC-20 tokens. For native assets, it directly retrieves the balance using the <mark style="color:red;"><strong>balance</strong></mark> opcode. For ERC-20 tokens, it constructs a call to the <mark style="color:red;"><strong>balanceOf</strong></mark> function of the token contract, passing the target address as an argument. If the call fails, it reverts with the returned data.</td></tr><tr><td><mark style="color:red;"><strong>transferFrom</strong></mark> </td><td>The <mark style="color:red;"><strong>transferFrom</strong></mark> function performs a safe transfer of a specified asset from one address to another. It uses inline assembly to prepare a call to the <mark style="color:red;"><strong>transferFrom</strong></mark> function of the asset’s contract, passing the sender’s address, the recipient’s address, and the amount to be transferred. If the transfer operation fails, it reverts with a <mark style="color:red;"><strong>TransferFromFailed</strong></mark> error. This function ensures that asset transfers are handled securely and correctly.</td></tr><tr><td><mark style="color:red;"><strong>transfer</strong></mark> </td><td>The <mark style="color:red;"><strong>transfer</strong></mark> function facilitates the transfer of a specified amount of an asset to a recipient address. If the asset is native (Ether), it uses a low-level call to transfer the amount directly. If the transfer fails, it reverts with a <mark style="color:red;"><strong>TransferFailed</strong></mark> error. For non-native assets, it constructs a call to the <mark style="color:red;"><strong>transfer</strong></mark> function of the asset’s contract using inline assembly. If the transfer operation fails, it also reverts with a <mark style="color:red;"><strong>TransferFailed</strong></mark> error. This function ensures that both native and non-native asset transfers are handled securely.</td></tr><tr><td><mark style="color:red;"><strong>approve</strong></mark> </td><td>The <mark style="color:red;"><strong>approve</strong></mark> function allows a spender address to spend a specified amount of an asset on behalf of the owner. It constructs a call to the <mark style="color:red;"><strong>approve</strong></mark> function of the asset’s contract using inline assembly. If the approval operation fails, it attempts to reset the allowance to zero and then re-approve the specified amount. If these attempts fail, it reverts with an <mark style="color:red;"><strong>ApprovalFailed</strong></mark> error. This function ensures that the approval process is robust and handles potential issues with resetting allowances.</td></tr><tr><td><mark style="color:red;"><strong>permit</strong></mark></td><td>The <mark style="color:red;"><strong>permit</strong></mark> function allows for the approval of a spender to spend a specified amount of an asset on behalf of the owner, using a signature. This function is useful for ERC-20 tokens that support the <mark style="color:red;"><strong>permit</strong></mark> function, enabling gasless approvals. It constructs a call to the <mark style="color:red;"><strong>permit</strong></mark> function of the asset’s contract using inline assembly, passing the owner’s address, spender’s address, amount, deadline, and the signature components (v, r, s). If the permit operation fails, it reverts with a <mark style="color:red;"><strong>PermitFailed</strong></mark> error.</td></tr><tr><td><mark style="color:red;"><strong>isSuccessful</strong></mark> </td><td>The <mark style="color:red;"><strong>isSuccessful</strong></mark> function checks if a call to a target contract was successful. It takes the target address, a success flag, and the returned data as inputs. If the call was successful and the returned data is empty, it checks if the target address is a contract by verifying the code length. If the returned data is not empty, it loads the result from the data using inline assembly. This function ensures that the success of a call is accurately determined, handling both contract and non-contract addresses.</td></tr><tr><td><mark style="color:red;"><strong>execute</strong></mark> </td><td>The <mark style="color:red;"><strong>execute</strong></mark> function performs a low-level call to a target contract, handling both native and non-native assets. It uses inline assembly to construct and execute the call, passing the necessary parameters such as the target address (<mark style="color:red;"><strong>self</strong></mark>), the amount of native asset to send (<mark style="color:red;"><strong>currentNativeAmount</strong></mark>), and pointers to the input and output data. The function includes an internal helper function, <mark style="color:red;"><strong>isSuccessfulCall</strong></mark>, which determines if the call was successful by checking the return data size and the existence of code at the target address. If the call fails, it reverts with the returned data. This function ensures that low-level calls are executed safely and correctly, providing a robust mechanism for interacting with other contracts.</td></tr></tbody></table>
