Only address type does not pass truffle test - solidity

I did the truffle test.
As shown below,everything else passes, but only the address type(address public custodian)does not pass the test.
Advice, please.
Contract: Fundraiser
initialization
✔ gets the beneficiary name
✔ gets the beneficiary url
✔ gets the beneficiary image url
✔ gets the beneficiary description
✔ gets the beneficiary
1) gets the cunstodian
No events were emitted
5 passing (203ms)
1 failing
Contract: Fundraiser
initialization
gets the cunstodian:
TypeError: fundraiser.cunstodian is not a function
at Context. (test/fundraiser_test.js:54:38)
at processImmediate (node:internal/timers:466:21)Fundraiser initialization
Fundraiser.sol
pragma solidity >0.4.23 <0.7.0;
contract Fundraiser{
string public name;
string public url;
string public imageURL;
string public description;
address payable public beneficiary;  
# falls to the test
address public custodian;
constructor(
string memory _name,
string memory _url,
string memory _imageURL,
string memory _description,
address payable _beneficiary,
address _custodian
)
public
{
name = _name;
url = _url;
imageURL = _imageURL;
description = _description;
beneficiary= _beneficiary;
custodian = _custodian;
}
}
test/fundraiser_test.js
const FundraiserContract = artifacts.require("Fundraiser");
contract("Fundraiser", accounts => {
let fundraiser;
const name = "Beneficiary Name";
const url = "beneficiaryname.org";
const imageURL="https://placeKitten.com/600/350";
const description = "Beneficiary description";
const beneficiary = accounts[1];
const cunstodian = accounts[0];
beforeEach(async () => {
fundraiser = await FundraiserContract.new(
name,
url,
imageURL,
description,
beneficiary,
cunstodian
)
});
describe("initialization", () => {
it("gets the beneficiary name", async () => {
const actual = await fundraiser.name();
assert.equal(actual, name, "names should match");
});
it("gets the beneficiary url", async () => {
const actual = await fundraiser.imageURL();
assert.equal(actual, imageURL, "imageURL should match");
});
it("gets the beneficiary image url", async () => {
const actual = await fundraiser.name();
assert.equal(actual, name, "names should match");
});
it("gets the beneficiary description", async () => {
const actual = await fundraiser.description();
assert.equal(actual, description, "description should match");
});
it("gets the beneficiary", async () => {
const actual = await fundraiser.beneficiary();
assert.equal(actual, beneficiary, "beneficiary should match");
});
it("gets the cunstodian", async () => {
const actual = await fundraiser.cunstodian();
assert.equal(actual, cunstodian, "cunstodian should match");
});
});
});;
source「
Hands-On Smart Contract Development with Solidity and Ethereum」

Related

Testing the safeMint function

I am trying to successfully write a unit test for my safeMint function below.
Here is my current test:
const assert = require("assert");
const { accounts } = require("#openzeppelin/test-environment");
const ComNFT = artifacts.require("ComNFT");
const { expect } = require("chai");
// describe('ComNFT', () => {
// let accounts;
let comNFT;
beforeEach(async () => {
accounts = await web3.eth.getAccounts();
comNFT = await ComNFT.new({ from: accounts[0] });
//comNFT = await ComNFT.at("");
// console.log(comNFT.address);
});
it('should fail when called by a non-owner account', async () => {
try {
await web3.eth.sendTransaction({
from: accounts[1], // The non-owner account
to: comNFT.address, // The contract address
data: comNFT.methods.safeMint(accounts[1], 'token URI').encodeABI() // The function call and arguments, encoded as ABI
});
assert.fail('Expected error not thrown');
} catch (error) {
assert(error.message.includes('onlyOwner'), 'Expected "onlyOwner" error message not found');
}
});
it('should be able to mint a new token', async () => {
await web3.eth.sendTransaction({
from: accounts[0], // The owner account
to: comNFT.address, // The contract address
data: comNFT.methods.safeMint(accounts[1], 'token URI').encodeABI() // The function call and arguments, encoded as ABI
});
const tokenURI = await comNFT.tokenURI(1); // Assume the token ID is 1
assert.equal(tokenURI, 'token URI');
});
function safeMint(address to, string memory uri) public onlyOwner {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
}
I am getting a failure message after i run npx truffle test " 1) "before each" hook for "should fail when called by a non-owner account"
0 passing (3s)
1 failing
"before each" hook for "should fail when called by a non-owner account":
TypeError: Assignment to constant variable.
at Context. (test/ComNFT.js:11:12)"
Can someone suggest a way of me successfully writing a test that calls safeMint?
The other test "itshould fail when called by a non-owner account" is also not running?
Thanks
safeMint function has onlyowner modifir, you should call safeMint function with the owner address that is accounts[0] (not accounts[1])

Can't get signer

Trying to read a transfer event from the ENS contract.
const listenToEvent = () => {
const contract = new ethers.Contract(
"0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85",
erc721Abi,
signer
);
contract.on("Transfer", (from, to, tokenId, event) => {
let data = {
from,
to,
tokenId: tokenId.toString(),
event,
};
console.log(data);
});
};
const balance = async (tokenAddress) => {
const contract = new ethers.Contract(tokenAddress, erc721Abi, signer);
const balance = await contract.balanceOf(account);
console.log(balance.toString());
};
const connect = async () => {
if (typeof window.ethereum !== "undefined") {
const accounts = await window.ethereum.request({
method: "eth_requestAccounts",
});
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
setSigner(signer);
listenToEvent();
setAccount(accounts[0]);
} else {
console.log("Please install metamask.");
}
};
In my console it gives me this error:
Uncaught (in promise) Error: events require a provider or a signer with a provider (operation="once", code=UNSUPPORTED_OPERATION, version=contracts/5.7.0)

how do I fix this error? ReferenceError: totalSupply is not defined

Im using a course, and I got this error:
ReferenceError: totalSupply is not defined
and Idk what it means by that, cause I never got this error before.
can somebody help me fix this error? thanks
and this is my code:
const { assert } = require("chai");
const KryptoBird = artifacts.require("KryptoBird");
// check for chai
require('chai')
.use(require('chai-as-promised'))
.should()
contract('KryptoBird', (accounts) => {
let contract
before( async () => {
contract = await KryptoBird.deployed()
})
describe('deployment', async() => {
it("deploys successfully", async () => {
const address = contract.address;
assert.notEqual(address, '')
assert.notEqual(address, null)
assert.notEqual(address, undefined)
assert.notEqual(address, 0x0)
})
it('has a name', async() => {
const name = await contract.name()
assert.equal(name, 'KryptoBird')
})
it('has a symbol', async() => {
const symbol = await contract.symbol()
assert.equal(symbol, 'KBIRDZ')
})
})
describe('minting', async ()=> {
it('creates a new token', async ()=> {
const result = await contract.mint('https...1')
const totalSupply = await contract.totalSupply();
assert.equal(totalSupply, 1)
const event = result.logs[0].args
assert.equal(event._from, '0x0000000000000000000000000000000000000000', 'from is the contract')
assert.equal(event._to, accounts[0], 'to is msg.sender')
await contract.mint('https...1').should.be.rejected
})
})
describe('indexing', async()=> {
it('lists KryptoBirdz', async()=> {
// Mint three new tokens
await contract.mint('https...2')
await contract.mint('https...3')
await contract.mint('https...4')
const totalSupply = await contract.totalSupply()
})
let result = []
let KryptoBird
for(i = 1; i <= totalSupply; i++) {
KryptoBird = await contract.kryptoBirdz(i)
result.push(KryptoBird)
}
let expected = ['https...1','https...2','https...3','https...4']
assert.equal(result.join(','), expected.join(','))
})
})
if u need another contract, just tell me, and if u could help me, thanks so much, because I need to finish this today. I've been trying to fix this for 2 hours, it didnt work. so please, if u could help me, it would mean a LOT to me.
here:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import './ERC721Connecter.sol';
contract KryptoBird is ERC721Connecter {
string[] public kryptoBirdz;
mapping(string => bool) _kryptoBirdzExists;
function mint(string memory _kryptoBird) public {
require(!_kryptoBirdzExists[_kryptoBird],
'Error - kryptoBird already exists');
// this is deprecated - uint _id = KryptoBirdz.push(_kryptoBird);
kryptoBirdz.push(_kryptoBird);
uint _id = kryptoBirdz.length - 1;
// .push no logner returns the length but a ref to the added element
_mint(msg.sender, _id);
_kryptoBirdzExists[_kryptoBird]=true;
}
constructor() ERC721Connecter('KryptoBird','KBIRDZ')
{}
}

How to transfer reward token to contract in Test Case

I am working on a sample contract which should provide a reward for the user. The winner gets the reward as Token.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.5;
contract LeagueWinners {
struct Winner {
bool exists;
bool claimed;
uint256 reward;
}
mapping(address=>Winner) public winners;
mapping (address => bool) private AuthAccounts;
IERC20 private rewardTokenAddr;
modifier onlyAuthAccounts() {
require(AuthAccounts[msg.sender], "Auth: caller is not the authorized");
_;
}
constructor (address _rewardTokenAddr) {
rewardTokenAddr = IERC20(_rewardTokenAddr);
AuthAccounts[msg.sender] = true;
AuthAccounts[_addr_1] = true;
AuthAccounts[_addr_2] = true;
}
function addWinner(address _address, uint256 _amount ) public {
Winner storage winner = winners[_address];
winner.exists = true;
winner.reward = _amount;
}
function claimPrize() public {
Winner storage winner = winners[msg.sender];
require(winner.exists, "Not a winner");
require(!winner.claimed, "Winner already claimed");
winner.claimed = true;
rewardTokenAddr.safeTransfer(msg.sender, winner.tokenAmount);
}
}
Test cases is failing when the user is trying to claim the prize. I assume there is no reward token in the contract so its failing.
const { expect } = require("chai");
const { ethers } = require("hardhat");
const hre = require("hardhat");
describe("LeagueWinners", function () {
let rewardTokenAddr = "0xAddr.....";
before(async () => {
LeagueWinners = await ethers.getContractFactory("LeagueWinners");
leagueWiners = await LeagueWinners.deploy(rewardTokenAddr);
await leagueWiners.deployed();
[owner, winner1, winner2, nonwinner] = await ethers.getSigners();
});
it("Claim Tokens to be deployed and verify owner", async function () {
expect(await leagueWiners.owner()).to.equal(owner.address);
});
it("Add Winner", async function () {
winner = await leagueWiners
.connect(owner)
.addWinner(
"winner1.address",
"50000000000000000000"
);
});
it("Confirm Winner Added with proper reward", async function () {
winner = await leagueWiners.winners(winner1.address);
expect(winner.reward).to.equal("50000000000000000000");
});
it("Non winner cannot claim", async function () {
await expect(
leagueWiners.connect(nonwinner).claimReward()).to.be.revertedWith("Not a winner");
});
it("Winner to claim", async function () {
await leagueWiners.connect(winner1).claimPrize();
winner = await leagueWiners.winners(winner1.address);
expect(winner.claimed).to.equal(true);
});
});
Error:
Error: VM Exception while processing transaction: reverted with reason string 'Address: call to non-contract'
This line is causing the error
await leagueWiners.connect(winner1).claimReward();
From the smart contract source that you provided I see that the name of function is claimPrize() not claimReward()
Maybe can work if you change to:
leagueWiners.connect(winner1).claimPrize();

Test cases failing due to custom modifier

I am new to solidity and trying to code it on my own before using open Zepplin plugins.
Here is the contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.5;
contract LeagueWinners {
struct Winner {
bool exists;
bool claimed;
uint256 reward;
}
mapping(address=>Winner) public winners;
mapping (address => bool) private AuthAccounts;
modifier onlyAuthAccounts() {
require(AuthAccounts[msg.sender], "Auth: caller is not the authorized");
_;
}
constructor () {
AuthAccounts[_addr_1] = true;
AuthAccounts[_addr_2] = true;
}
function addWinner(address _address, uint256 _amount ) public {
Winner storage winner = winners[_address];
winner.exists = true;
winner.reward = _amount;
}
}
I know we have the Ownable plugin from openzepplin. but just trying with my own modifier as I want 2 users to add winners.
The contract works well. but I am facing issues in writing test cases.
const { expect } = require("chai");
const { ethers } = require("hardhat");
const hre = require("hardhat");
describe("LeagueWinners", function () {
before(async () => {
LeagueWinners = await ethers.getContractFactory("LeagueWinners");
leagueWiners = await LeagueWinners.deploy();
await leagueWiners.deployed();
[owner] = await ethers.getSigners();
});
it("Claim Tokens to be deployed and verify owner", async function () {
expect(await leagueWiners.owner()).to.equal(owner.address);
});
it("Add Winner", async function () {
winner = await leagueWiners
.connect(owner)
.addWinner(
"_addr",
"50000000000000000000"
);
});
});
Add winner is getting failed, not sure how to pass the AuthAccounts. Any guidance will be great help
Error
Error: VM Exception while processing transaction: reverted with reason string 'Auth: caller is not the authorized'
You don't pass any addresses to the constructor here:
constructor () {
AuthAccounts[_addr_1] = true;
AuthAccounts[_addr_2] = true;
}
You need to add the _addr_1 and _addr_2 into the constructor like this:
constructor (address _addr_1, address _addr_2) {
AuthAccounts[_addr_1] = true;
AuthAccounts[_addr_2] = true;
}
The compiler shouldn't let you compile this contract so I'm not sure how it lets you deploy it.
Then in your test you need to pass the arguments like this:
before(async () => {
LeagueWinners = await ethers.getContractFactory("LeagueWinners");
leagueWiners = await LeagueWinners.deploy(addr1, addr2); // HERE
await leagueWiners.deployed();
[owner] = await ethers.getSigners();
});
After spending a few days, made a solution in this way.
constructor () {
AuthAccounts[msg.sender] = true;
AuthAccounts[_addr_1] = true;
AuthAccounts[_addr_2] = true;
}
As i was hardcoding other addresses, it was not possible to get signer info in the test cases. Passing msg.sender in AuthAccounts helped to achieve that and test cases got passed.
Let me know if there are any other work arounds.