Closed 847850277 closed 5 months ago
@847850277 did you find a solution? What was the reason for the bug?
@847850277 did you find a solution? What was the reason for the bug?
I haven't solved it yet. I closed it because I feel like no one is paying attention. I don't know the reason yet. I'm still trying simpler Dispatcher and Library examples on the Sepolia network. If I solve it, I will post simple examples later.
@847850277 you can reopen the issue, the maintainers are working on many projects at the same time and will look into this issue as soon as they can.
I'll find some bandwidth to take a look at this myself today, will get back to you once I do.
@847850277 you can reopen the issue, the maintainers are working on many projects at the same time and will look into this issue as soon as they can.
I'll find some bandwidth to take a look at this myself today, will get back to you once I do.
Okay, I have reopened it. Thank you for your reply。
@847850277 are you using the same openzeppelin
dependency version as is used in the repo (v0.11.0)? If so, I may have found the cause of your error.
This is the line that may be the problem (in add_liquidity
ofc):
token0.transfer_from(caller, this, amount0);
OpenZeppelin's ERC20.transfer_from
function calls _spend_allowance
before it calls _transfer
, and it performs an underflowing subtraction (see _spend_allowance source):
fn _spend_allowance(
ref self: ComponentState<TContractState>,
owner: ContractAddress,
spender: ContractAddress,
amount: u256
) {
let current_allowance = self.ERC20_allowances.read((owner, spender));
if current_allowance != BoundedInt::max() {
self._approve(owner, spender, current_allowance - amount);
}
}
This underflow can happen when current_allowance
is smaller than the transfer amount, i.e. when the calling contract wasn't approved for enough tokens.
(Note: this issue has been fixed already in v0.12.0 - they added an assertion that there's enough allowance prior to calling _approve
, and they added a clearer error message)
Can you check if you have increased the allowance of the AMM contract by first calling ERC20.approve with an amount larger than the one you're trying to add as liquidity (note that you need to approve enough allowance for both ETH and STRK)?
@847850277 Sorry for responding a bit late, and thank you @misicnenad for taking the time to help find the issue. We will update OZ dependency and adds more information in #218
@847850277 are you using the same
openzeppelin
dependency version as is used in the repo (v0.11.0)? If so, I may have found the cause of your error.This is the line that may be the problem (in
add_liquidity
ofc):token0.transfer_from(caller, this, amount0);
OpenZeppelin's
ERC20.transfer_from
function calls_spend_allowance
before it calls_transfer
, and it performs an underflowing subtraction (see _spend_allowance source):fn _spend_allowance( ref self: ComponentState<TContractState>, owner: ContractAddress, spender: ContractAddress, amount: u256 ) { let current_allowance = self.ERC20_allowances.read((owner, spender)); if current_allowance != BoundedInt::max() { self._approve(owner, spender, current_allowance - amount); } }
This underflow can happen when
current_allowance
is smaller than the transfer amount, i.e. when the calling contract wasn't approved for enough tokens.(Note: this issue has been fixed already in v0.12.0 - they added an assertion that there's enough allowance prior to calling
_approve
, and they added a clearer error message)Can you check if you have increased the allowance of the AMM contract by first calling ERC20.approve with an amount larger than the one you're trying to add as liquidity (note that you need to approve enough allowance for both ETH and STRK)?
That's right, the version is v0.11.0. I will do it according to your suggestion immediately. 👍
@847850277 Sorry for responding a bit late, and thank you @misicnenad for taking the time to help find the issue. We will update OZ dependency and adds more information in #218
That's great. Thank you for taking the time to reply。🎉
@847850277 did this solve your problem? If so, we can mark the issue as complete
@847850277 did this solve your problem? If so, we can mark the issue as complete
I am still trying, I am still in the deployment contract, but there seems to be some issues with Sepolia deployment now. When I try to solve it, I will close it。
@misicnenad Hi, I guess the problem may be in the transfer. I updated the openzeppelin to v0.13.0 while simplifying the code. The simplified code is as follows.
#[starknet::interface]
pub trait ICaller<TContractState> {
fn transfer(
ref self: TContractState, addr: starknet::ContractAddress, recipient: starknet::ContractAddress, amount: u256
) -> bool;
fn transfer_1(
ref self: TContractState, addr: starknet::ContractAddress, recipient: starknet::ContractAddress, amount: u256
) -> bool;
fn approve(ref self: TContractState, addr: starknet::ContractAddress, recipient: starknet::ContractAddress, amount: u256) -> bool;
}
#[starknet::contract]
pub mod transfer_eth {
// We need to import the dispatcher of the callee contract
// If you don't have a proper import, you can redefine the interface by yourself
use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};
use starknet::ContractAddress;
#[storage]
struct Storage {}
#[constructor]
fn constructor(ref self: ContractState) {
}
#[abi(embed_v0)]
impl ICallerImpl of super::ICaller<ContractState> {
fn transfer(ref self: ContractState, addr: ContractAddress,recipient: ContractAddress, amount: u256) -> bool{
IERC20Dispatcher { contract_address: addr }.transfer(recipient,amount);
return true;
}
fn transfer_1(ref self: ContractState, addr: ContractAddress,recipient: ContractAddress, amount: u256) -> bool{
IERC20Dispatcher { contract_address: addr }.approve(recipient,amount);
IERC20Dispatcher { contract_address: addr }.transfer(recipient,amount);
return true;
}
fn approve(ref self: ContractState, addr: ContractAddress,recipient: ContractAddress, amount: u256) -> bool{
IERC20Dispatcher { contract_address: addr }.approve(recipient,amount);
return true;
}
}
}
Deploying it on the Sepollia network will result in errors when calling transfer1, transfer1, and transfer1.
The logic of transfer is the transfer function of IERC20Dispatcher.
fn transfer(ref self: ContractState, addr: ContractAddress,recipient: ContractAddress, amount: u256) -> bool{
IERC20Dispatcher { contract_address: addr }.transfer(recipient,amount);
return true;
}
The logic of transfer_1 is that IERC20Dispatcher first approves, and then the transfer function is used
fn transfer_1(ref self: ContractState, addr: ContractAddress,recipient: ContractAddress, amount: u256) -> bool{
IERC20Dispatcher { contract_address: addr }.approve(recipient,amount);
IERC20Dispatcher { contract_address: addr }.transfer(recipient,amount);
return true;
}
Transfer calls and errors.
The call and error of transfer_1.
The approve call is correct
This is the contract address, you can also call it to see if there will be an error message
@847850277 it makes sense that transfer
and transfer_1
would fail, as your Caller
contract has no ETH token to transfer.
Before your wallet allows you to confirm the transaction, it simulates it and realizes that it would fail because your contract has no ETH to send. That's why it displays the u256 sub overflow
error.
Make sure your Caller
contract has enough tokens to transfer before you try calling any of its "transfer" functions.
P.S. By extension, it makes sense that approve
would be successful, because you can always approve tokens, even if you do not have them - there's no subtraction happening.
@misicnenad I used the faucet to transfer an ETH to the contract address, and then called transfer or transfer_1, both of which run correctly. appreciate for your support,Thanks to your help, this issue has been solved.I learn too much from this issue.
Under the Sepolia network,I want to achieve mutual swap between ETH and STAR I copied the code based on the example and removed the code related to the feed. Declared and deployed the contract, with the constructor parameters being the token contract addresses for eth and starknet. When I execute the add_liquidity function, it returns an error。 Can you spare some time to help me find out why we can't add liquidity @julio4
The contract code is as follows
the parameters of the constructor first is
0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7
,second is0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d
. The two addresses are the contract addresses for eth and Stark, respectively.and the deployed contract address
the error info is
I guess there was a problem with the contract Dispatcher, and then I simplified the contract to call the transfer of the token contract. It also returns
u256_sub Overflow
Now, I'm stuck in a problem and don't know how to solve it.The simplified contract code is as follows