0

Having trouble understanding how to correctly implement Approve and transferFrom. Some guidance would be much appreciated, thank you for your time. Below is my Deposit function:

/ Users can deposit DAI to the contract
function deposit(uint deposit_amount) public {
bool withdrawalLock = false;

// Access the contract's state before making the external call
require(withdrawalAllowed, "Withdrawals are not currently allowed");
require(deposit_amount >= MIN_DEPOSIT && deposit_amount <= MAX_DEPOSIT, "Invalid 
deposit amount");

// Use a reentrancy lock to prevent untrusted callees from re-entering the contract
require(!withdrawalLock, "Reentrancy detected");
withdrawalLock = true;

// Approve DAI token
IERC20(daitoken).approve(address(this), deposit_amount);
// Transfer the DAI to the contract
IERC20(daitoken).transferFrom(msg.sender, address(this), deposit_amount);
// Update the user's balance in the mapping
userBalances[msg.sender] = userBalances[msg.sender].add(deposit_amount);
emit Deposit(msg.sender, deposit_amount);

// Unlock the contract to allow future withdrawals
withdrawalLock = false;
}

This selfdestruct function does work if the some DAI is sent to the contract address so i am pretty sure the IERC20 interface is working correctly. However in this case the user should use the Deposit function so they can then call Refund on their own.

// Contract is owned by onlyOwner
contract mortal is owned {

// Only owner can shutdown this contract.
function destroy() public onlyOwner {
    daitoken.transfer(owner, daitoken.balanceOf(address(this)));
    selfdestruct(payable(msg.sender));
    }
}

1 Answer 1

0

To deposit funds in the smart contract user should approve the contract to "take" an amount of funds, he must call the approve function (he is the sender of the transaction), and not the contract who calls the approve (in this way he can approve to take all the funds of the user and that's not what you wanna do ), so you have to remove approve inside the deposit function, the user should call it outside the contract and sign the transaction with his private key .

deposit function :

Users can deposit DAI to the contract
function deposit(uint deposit_amount) public {
bool withdrawalLock = false;

// Access the contract's state before making the external call
require(withdrawalAllowed, "Withdrawals are not currently allowed");
require(deposit_amount >= MIN_DEPOSIT && deposit_amount <= MAX_DEPOSIT, "Invalid 
deposit amount");

// Use a reentrancy lock to prevent untrusted callees from re-entering the 
contract
require(!withdrawalLock, "Reentrancy detected");
withdrawalLock = true;

// Transfer the DAI to the contract
IERC20(daitoken).transferFrom(msg.sender, address(this), deposit_amount);
// Update the user's balance in the mapping
userBalances[msg.sender] = userBalances[msg.sender].add(deposit_amount);
emit Deposit(msg.sender, deposit_amount);

// Unlock the contract to allow future withdrawals
withdrawalLock = false;
}

outside the contract :

daitoken.approve(<contract_address>, deposit_amount, {"from": user_account});
5
  • So i should place this outside of the deposit function? function Approve() external { daitoken.approve(address(this), deposit_amount, {"from": msg.sender}); }
    – Hari
    Dec 21, 2022 at 9:25
  • you should place it where the user can call it directly without going throught a contract .
    – noro meb
    Dec 21, 2022 at 10:31
  • deploy your contract, and then call approve with user account passing the contract address and amount in the scripts if you are using python or js or directly from the account if you are using remix
    – noro meb
    Dec 21, 2022 at 10:33
  • ooooohh I see so that bit is in fact like a prerequisite for the user to use the function of the contract; we are just facilitating that step for them so it doesn't belong in the contract proper.
    – Hari
    Dec 21, 2022 at 12:47
  • the user should be the only one who approve who spend what amount of his funds, if the contract can approve to spend user's funds he can empty the wallet. So the user approve (outside the contract) that the contract can get funds, and than contract transform funds from the user account to itself . i wish it could help
    – noro meb
    Dec 21, 2022 at 15:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.