Files

49 lines
1.6 KiB
Solidity

// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.17;
/// @title SecuredTokenTransfer - Secure token transfer
abstract contract SecuredTokenTransfer {
/// @dev Transfers a token and returns if it was a success
/// @param token Token that should be transferred
/// @param receiver Receiver to whom the token should be transferred
/// @param amount The amount of tokens that should be transferred
function _transferToken(
address token,
address receiver,
uint256 amount
) internal returns (bool transferred) {
require(token != address(0), "token can not be zero address");
require(token.code.length > 0, "token contract doesn't exist");
// 0xa9059cbb - keccack("transfer(address,uint256)")
bytes memory data = abi.encodeWithSelector(
0xa9059cbb,
receiver,
amount
);
assembly {
// We write the return value to scratch space.
// See https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_memory.html#layout-in-memory
let success := call(
sub(gas(), 10000),
token,
0,
add(data, 0x20),
mload(data),
0,
0x20
)
switch returndatasize()
case 0 {
transferred := success
}
case 0x20 {
transferred := iszero(or(iszero(success), iszero(mload(0))))
}
default {
transferred := 0
}
}
}
}