@PaulS96 one thing i forgot to mention is that your witdraw function was payable until i changed it. functions should only be payable if your sending ether into a contract. instead for withdrawing functions you only need the recipient address to be payable and then use the built in transfer function or the call function to send the funds to the recipient.
hey sir, im doing testing of adding tokens by owner. 0 is account of owner then why my test is failing ?
Contract: Dex
1) shoul only possibile for owners to add tokens
> No events were emitted
0 passing (6s)
1 failing
- Contract: Dex
shoul only possibile for owners to add tokens :
ReferenceError: Cannot access āDexā before initialization
at Context. (test\Wallettest.js:7:11)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
This version of ĀµWS is not compatible with your Node.js build:
Error: Cannot find module ā./uws_win32_ia32_72.nodeā
Falling back to a NodeJS implementation; performance may be degraded.
const Cpt= artifacts.require("Cpt")
const Dex= artifacts.require("Dex")
const truffleAssert = require('truffle-assertions');
contract ("Dex", accounts =>{
it ("shoul only possibile for owners to add tokens ", async() =>{
let Dex = await Dex.deployed()
let Cpt = await Cpt.deployed()
await truffleAssert.passes(
Dex.addtoken(web3.utils.fromUtf8("Cpt"),Cpt.address,{ from: accounts[0]}))
})
})
can u see why test is failing?
Might be a require
getting triggered, can you share the contract ?? it would be much easier for us if you create a github repo for the project.
Carlos Z
This is my code.
taking a look at the forum and code on github, I see that in my code it is missing,
check that the tokens exist and event (I will add this item next time).
I tried to use ādelegated callā to approve the expense, but this solution does not work. (I approved by the contract and not for user)
I have test my code using a token āmockDaiā, and i use this function " web3.utils.asciiToHex()" for convert string in byte32.
// SPDX-License-Identifier: Leluk911
pragma solidity 0.8.0;
import "../node_modules/@openzeppelin/contracts/interfaces/IERC20.sol";
import "../node_modules/@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract Wallet is ReentrancyGuard {
// use this struct for store token in wallet
struct Token {
bytes32 tiker;
address tokenAddress;
}
mapping(bytes32 => Token) TokenMapping;
// array for store Token for Token.tiker
bytes32[] public TokenList; // only list.. some information give in mapping TokenMapping
// duble mapping for balance every Token in wallet add
mapping(address => mapping(bytes32 => uint256)) public balances;
function addToken(bytes32 _tiker, address _tokenAddress)
external
nonReentrant
{
// add token information i wallet
TokenMapping[_tiker] = Token(_tiker, _tokenAddress);
// push only _tiker.. mapping need for take address.
TokenList.push(_tiker);
}
function deposit(uint256 _amount, bytes32 _tiker) external nonReentrant {
// before approve this spend
IERC20(TokenMapping[_tiker].tokenAddress).transferFrom(
msg.sender,
address(this),
_amount
);
balances[msg.sender][_tiker] += _amount;
}
function withdraw(uint256 _amount, bytes32 _tiker) external nonReentrant {
require(TokenMapping[_tiker].tokenAddress != address(0)); // address assigne not 0X00000
require(balances[msg.sender][_tiker] >= _amount, "balance insufficent"); // check balance before
balances[msg.sender][_tiker] -= _amount; //update balance befor transfer
IERC20(TokenMapping[_tiker].tokenAddress).transfer(msg.sender, _amount); // transfer
}
}
hey @LELUK911 i will have a look at your code now. are ypu able to post the link to your githib. one thing before i do is that you cannot use delegate call here for this to work. the approve function doesnt work here when you try to call it is because your dex contract makes an external call to your link token. therefore the caller is not you but rather your dex contract. so because this is the case the owner address and the spender address are the same here therefore the alloance will get increased for owner = your wallet and spender - your wallet. the only way to solve this is to execute approve and transferfrom seperately. which is annoying i know.
but anyways ill look at the rest of your code now if you can share the link to your github
in fact , my contractās allowance increas, i havenāt post on github.
but the function was more or less.
function approveDelegate(address _user, uint _amount, bytes32 _tiker) external{
address tiker = TokenMapping[_tiker].tokenAddress;
(bool success,) = tiker.delegatecall(abi.encodeWithSignature("approve(address, uint256)", _user,_amount));
require(success,"transaction faill");
}
Are you sure this works. im pretty sure your code above wont work. i know from experience that trying to call the approve function externally from another contract wiht delegate call doesnt work as the caller will always be the contract making the call and not the wallet address calling the function itself.
there is no way to bundle an approval and a transferfrom in solidity with erc20s
if this does somehow work and im missing anything do share because fom what i understand is it cant be done.
no no, i explained myself badly because of my bad english.
this function, yes, it works but as you say only for the contract that calls the call ā¦ therefore the expense is authorized for the contract and not for the user, who, as you say, must authorize the expense himself.
in fact this would be a bad resolution of my experiment, Iām trying to use a different way
PS. I hope my translation was more clear this time
yes your exactly right. it is annoying and it would be very handy if you could use delegate call to call a tokens approve function externally but sadly it does not work. very great that you have done your own research to experiment with some lower level functionalitites built into solididy such as delegatcall it shows your on the right path and doing even more learning on your own. great stuff
Good Evening!
Having some challenges, wondering if anyone can help me with some suggestions about fixing this:
Source file requires different compiler version (current compiler is 0.8.12+commit.f00d7308.Emscripten.clang) - note that nightly builds are considered to be strictly less than the released version
I tried using the following, but none of these work:
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
Pragma solidity >=4.5.0 <0.8.0;
pragma solidity ^0.8.0;
pragma solidity >=0.4.22 <0.8.0;
pragma solidity >=0.6.0 <0.8.0;
Much appreciate!
in your projects truffle config file make sure that your compiler version matxhes the one your using in your smart conttrat file
Awesome! I will check that outš¤©
cool let me know if you get it working
Hello @mcgrane5
Having some issues, I did exit VScode just in case it was login/exit issue but when I try to migrate it doesnāt work.
Compiler error msg:
2_wallet_migration.js
=====================
ReferenceError: Wallet is not defined
at module.exports (/Users/hermevillaparedes/Ethereum-201/DEX/migrations/2_wallet_migration.js:4:19)
at Migration._load (/usr/local/lib/node_modules/truffle/build/webpack:/packages/migrate/Migration.js:55:1)
at processTicksAndRejections (internal/process/task_queues.js:88:5)
at Migration.run (/usr/local/lib/node_modules/truffle/build/webpack:/packages/migrate/Migration.js:217:1)
at Object.runMigrations (/usr/local/lib/node_modules/truffle/build/webpack:/packages/migrate/index.js:150:1)
at Object.runFrom (/usr/local/lib/node_modules/truffle/build/webpack:/packages/migrate/index.js:110:1)
at Object.run (/usr/local/lib/node_modules/truffle/build/webpack:/packages/migrate/index.js:87:1)
at runMigrations (/usr/local/lib/node_modules/truffle/build/webpack:/packages/core/lib/commands/migrate/run.js:76:1)
at Object.module.exports [as run] (/usr/local/lib/node_modules/truffle/build/webpack:/packages/core/lib/commands/migrate/run.js:44:1)
at Command.run (/usr/local/lib/node_modules/truffle/build/webpack:/packages/core/lib/command.js:189:1)
I would love your guidance on this challenge:
wallet.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
import "../node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../node_modules/@openzeppelin/contracts/utils/math/SafeMath.sol";
import "../node_modules/@openzeppelin/contracts/access/Ownable.sol";
contract Wallet is Ownable {
using SafeMath for uint256;
struct Token {
bytes32 ticker;
address tokenAddress;
}
mapping(bytes32 => Token) public tokenMapping;
bytes32[] public tokenList;
mapping(address => mapping(bytes32 => uint256)) public balances;
modifier tokenExist(bytes32 ticker) {
require(tokenMapping[ticker].tokenAddress != address(0), "token does not exist");
_;
}
function addToken(bytes32 ticker, address tokenAddress) onlyOwner external {
tokenMapping[ticker] = Token(ticker, tokenAddress);
tokenList.push(ticker);
}
function deposit(uint amount, bytes32 ticker) tokenExist(ticker) external {
IERC20(tokenMapping[ticker].tokenAddress).transferFrom(msg.sender, address(this), amount);
balances[msg.sender][ticker] = balances[msg.sender][ticker].add(amount);
}
function withdraw(uint amount, bytes32 ticker) external {
require(tokenMapping[ticker].tokenAddress != address(0));
require(balances[msg.sender][ticker] >= amount, "Balance not sufficient");
balances[msg.sender][ticker] = balances[msg.sender][ticker].sub(amount);
IERC20(tokenMapping[ticker].tokenAddress).transfer(msg.sender, amount);
}
}
Tokens.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
import "../node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Link is ERC20 {
constructor() ERC20("Chainlink", "LINK") {
_mint(msg.sender, 1000);
}
}
2_wallet_migration.js
const Migrations = artifacts.require("Wallet");
module.exports = function (deployer) {
deployer.deploy(Wallet);
};
3_token_migration.js
const Migrations = artifacts.require("Link");
module.exports = function (deployer) {
deployer.deploy(Link);
};
Much appreciate!
hi everyone!
I have a small problem with my code, my first problem is that iām not good in a writing test (iām working on it), but in this case, I test my code in analytic mode and it seems that, for some obscure reason, I am unable to update the āamountā of the order in case this is less than the āmarket order amountā. . with a lot of provably I have the wrong approach with debug, and i donāt find my errorā¦
I have a small problem with my code, my first problem is that iām not good in a writing test (iām working on it), but in this case, I test my code in analytic mode and it seems that, for some obscure reason, I am unable to update the āamountā of the order in case this is less than the āmarket order amountā. . with a lot of provably I have the wrong approach with debug, and i donāt find my errorā¦
this is code:
the function that create error is : createMarketOrderā¦
// SPDX-License-Identifier: Leluk911
pragma solidity 0.8.0;
pragma experimental ABIEncoderV2;
import "./wallet.sol";
contract Dex is Wallet {
enum Side {
BUY,
SELL
}
struct Order {
uint256 Id;
address Trader;
Side side;
uint256 amount;
uint256 price;
bytes32 Tiker;
}
uint256 NewID = 0;
mapping(bytes32 => mapping(uint256 => Order[])) OrderBook;
function getOrderBook(bytes32 _tiker, Side _side)
external
view
returns (Order[] memory)
{
return OrderBook[_tiker][uint256(_side)];
}
function createLimitOrder(
uint256 _amount,
uint256 _price,
bytes32 _tiker,
Side _side
) external {
//tokenExist(_tiker) {
if (Side.BUY == _side) {
require(balances[msg.sender]["ETH"] >= _amount * _price);
} else if (Side.SELL == _side) {
require(balances[msg.sender][_tiker] >= _amount);
}
Order[] storage orders = OrderBook[_tiker][uint256(_side)];
orders.push(Order(NewID, msg.sender, _side, _amount, _price, _tiker));
uint256 i = orders.length > 0 ? orders.length - 1 : 0;
if (Side.BUY == _side) {
while (i > 0) {
if (orders[i - 1].price > orders[i].price) {
break;
}
Order memory ordersMove = orders[i - 1];
orders[i - i] = orders[i];
orders[i] = ordersMove;
i--;
}
} else if (Side.SELL == _side) {
while (i > 0) {
if (orders[i - 1].price < orders[i].price) {
break;
}
Order memory ordersMove = orders[i - 1];
orders[i - i] = orders[i];
orders[i] = ordersMove;
i--;
}
}
NewID++;
}
/
function createMarketOrder(
uint256 _amount,
bytes32 _tiker,
bytes32 _tikerExchange
) external {
// array da usare
Order[] storage orderSide = OrderBook[_tiker][1];
// se nn ci sono ordini ci mandi indietro
if (orderSide.length == 0) {
revert("Order not present or this amount of coin");
}
// variabili per gestire l'rodine d'acquisto
uint256 orderMArketLeft = _amount;
uint256 orderMarketComplete = 0;
// ciclo per pescare gli ordini nell array
for (
uint256 index = 0;
index < orderSide.length && orderMArketLeft > 0;
index++
) {
// se l'rodine che peschiamo non completa il nostro ordine rimanente
if (orderSide[index].amount < orderMArketLeft) {
// variabile che ci da la differenza per aggiornare le variabili e inviare i soldi
// aggiorniamo l'orderbook
uint256 orderMarketPending = orderMArketLeft -
orderSide[index].amount;
uint256 price = orderSide[index].price;
// aggiornamenyo variabili per il prossimo ciclo
orderMArketLeft -= orderMarketPending;
orderMarketComplete += orderMarketPending;
// trasferimento soldi dall user al wallet dell'order
//------> PS deve prima approvare la spesa
IERC20(TokenMapping[_tikerExchange].tokenAddress).transferFrom(
msg.sender,
address(this),
orderMarketPending * price
);
// aggiorniamo il bilancio del orderSeller
orderSide[index].amount = 0;
address OrderSeller = orderSide[index].Trader;
balances[OrderSeller][_tikerExchange] +=
orderMarketPending *
price;
//revert(" mi blocco qui al pimo if");
} else if (orderSide[index].amount > orderMArketLeft) {
// qua togliamo solo l'amount dall'ordine che rimane aperto comunque
orderSide[index].amount -= orderMArketLeft;
// riempiamo la variabile di completamento
orderMarketComplete += orderMArketLeft;
// operazioni di spostamento token
uint256 price = orderSide[index].price;
//------> PS deve prima approvare la spesa
IERC20(TokenMapping[_tikerExchange].tokenAddress).transferFrom(
msg.sender,
address(this),
orderMArketLeft * price
); // aggiorniamo l'orderbook
// aggiorniamo il bilancio del orderSeller
address OrderSeller = orderSide[index].Trader;
balances[OrderSeller][_tikerExchange] +=
orderMArketLeft *
price;
//revert(" mi blocco qui al secondo if");
}
}
while (orderSide.length > 0 && orderSide[0].amount == 0) {
for (uint256 i = 0; i < orderSide.length - 1; i++) {
orderSide[i] = orderSide[i + 1];
}
orderSide.pop();
}
}
}
hey @HRMS2021. yeah so the problem is in your migrations
const Migrations = artifacts.require("Wallet");
module.exports = function (deployer) {
deployer.deploy(Wallet);
};
your variable name is called Migrations
, the reason your getting the error saying that wallet is not defined is because you need to change Migrations
to Wallet
. so the fixed migrations is
const Wallet = artifacts.require("Wallet");
module.exports = function (deployer) {
deployer.deploy(Wallet);
};
let me know if this works
hi @LELUK911. would you be able to explain a little more. what do you mean by testing in analytic mode
. and also what is the error that your getting exactly. could you share a screenshot of the error please and i will be on standby to help
thank for your help.
for analitik test , i would tell that i doing one transaction for one,
ā> here deposit 2 eth
-> this is order book sell WETH
-> one order 1 weth ā¦
- usualy this transaction when fill one order that have amount > order , this not update orderbook and not send DAI for purchase.
- in this case , first order market, function. but if i try again , i have usaualy problem .
I hope you understand the problem.
the code function, but it dont work like i want