fix: Migrate transformers to smart contract compatible unsafeTransformerTransfer
[TKR-587] (#594)
* Use `call` instead of `transfer` in `LibERC20Transformer` * Since `transfer` only forwards 2300 gas it can cause an `out of gas` revert when the receipient is a smart contract. * Add `unsafeTransformerTransfer` and migrate `transformers` to use `unsafeTransformerTransfer` instead of `transformerTransfer` * Update .prettierignore
This commit is contained in:
@@ -61,7 +61,7 @@ contract AffiliateFeeTransformer is Transformer {
|
||||
amount = LibERC20Transformer.getTokenBalanceOf(fees[i].token, address(this));
|
||||
}
|
||||
if (amount != 0) {
|
||||
fees[i].token.transformerTransfer(fees[i].recipient, amount);
|
||||
fees[i].token.unsafeTransformerTransfer(fees[i].recipient, amount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -34,7 +34,9 @@ library LibERC20Transformer {
|
||||
/// This is just `keccak256('TRANSFORMER_SUCCESS')`.
|
||||
bytes4 internal constant TRANSFORMER_SUCCESS = 0x13c9929e;
|
||||
|
||||
/// @dev Transfer ERC20 tokens and ETH.
|
||||
/// @dev Transfer ERC20 tokens and ETH. Since it relies on `transfer` it may run out of gas when
|
||||
/// the `recipient` is a smart contract wallet. See `unsafeTransformerTransfer` for smart contract
|
||||
/// compatible transfer.
|
||||
/// @param token An ERC20 or the ETH pseudo-token address (`ETH_TOKEN_ADDRESS`).
|
||||
/// @param to The recipient.
|
||||
/// @param amount The transfer amount.
|
||||
@@ -50,6 +52,24 @@ library LibERC20Transformer {
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Transfer ERC20 tokens and ETH. For ETH transfer. It's not safe from re-entrancy attacks and the
|
||||
/// caller is responsible for gurading against a potential re-entrancy attack.
|
||||
/// @param token An ERC20 or the ETH pseudo-token address (`ETH_TOKEN_ADDRESS`).
|
||||
/// @param to The recipient.
|
||||
/// @param amount The transfer amount.
|
||||
function unsafeTransformerTransfer(
|
||||
IERC20TokenV06 token,
|
||||
address payable to,
|
||||
uint256 amount
|
||||
) internal {
|
||||
if (isTokenETH(token)) {
|
||||
(bool sent, ) = to.call{value: amount}("");
|
||||
require(sent, "LibERC20Transformer/FAILED_TO_SEND_ETHER");
|
||||
} else {
|
||||
token.compatTransfer(to, amount);
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Check if a token is the ETH pseudo-token.
|
||||
/// @param token The token to check.
|
||||
/// @return isETH `true` if the token is the ETH pseudo-token.
|
||||
|
@@ -65,7 +65,7 @@ contract PayTakerTransformer is Transformer {
|
||||
amount = data.tokens[i].getTokenBalanceOf(address(this));
|
||||
}
|
||||
if (amount != 0) {
|
||||
data.tokens[i].transformerTransfer(context.recipient, amount);
|
||||
data.tokens[i].unsafeTransformerTransfer(context.recipient, amount);
|
||||
}
|
||||
}
|
||||
return LibERC20Transformer.TRANSFORMER_SUCCESS;
|
||||
|
@@ -53,7 +53,7 @@ contract PositiveSlippageFeeTransformer is Transformer {
|
||||
uint256 transformerAmount = LibERC20Transformer.getTokenBalanceOf(fee.token, address(this));
|
||||
if (transformerAmount > fee.bestCaseAmount) {
|
||||
uint256 positiveSlippageAmount = transformerAmount - fee.bestCaseAmount;
|
||||
fee.token.transformerTransfer(fee.recipient, positiveSlippageAmount);
|
||||
fee.token.unsafeTransformerTransfer(fee.recipient, positiveSlippageAmount);
|
||||
}
|
||||
|
||||
return LibERC20Transformer.TRANSFORMER_SUCCESS;
|
||||
|
Reference in New Issue
Block a user