Transaction reverted during swapExactTokensForTokens (UniswapV2Router02, web3.js) - blockchain

I am attempting to swap ETH for DAI using the Uniswap Router, but am facing a problem where the transaction gets reverted, along with the following message: Transaction has been reverted by the EVM.
I am testing this on the Rinkeby Testnet.
Here is the full message, along with the accompanying block information:
Transaction has been reverted by the EVM:
{
"blockHash": "0xfaa3effa60d646ef4db959cba460dac74aafd1c0b667c91758be71a735f949ce",
"blockNumber": 9146763,
"contractAddress": null,
"cumulativeGasUsed": 1678679,
"effectiveGasPrice": "0x3b9aca09",
"from": "0xbd8b57fdbd794f125a9d6a3a7bd8958d46201b37",
"gasUsed": 30348,
"logs": [],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status": false,
"to": "0x7a250d5630b4cf539739df2c5dacb4c659f2488d",
"transactionHash": "0x7c5b33a7a751430ba0e0347a29b01a12db0b1da71a17a36deb4c773ea5ff483c",
"transactionIndex": 6,
"type": "0x0"
}
at Object.TransactionError (../node_modules/web3-core-helpers/lib/errors.js:87:21)
at Object.TransactionRevertedWithoutReasonError (../node_modules/web3-core-helpers/lib/errors.js:98:21)
at ../node_modules/web3-core-method/lib/index.js:394:57
I will also provide the NodeJS code I am running:
import Web3 from "web3";
const IERC20 = require('#uniswap/v2-periphery/build/IERC20.json')
const IPair = require('#uniswap/v2-core/build/IUniswapV2Pair.json')
const IFactory = require('#uniswap/v2-core/build/IUniswapV2Factory.json')
const IRouter = require('#uniswap/v2-periphery/build/IUniswapV2Router02.json')
export class TransactionService {
async transact() {
const privKey = "<privkey ommitted>";
var web3 = new Web3('https://rinkeby.infura.io/v3/<infura-rinkeby-path>');
var factory = new this.web3.eth.Contract(IFactory.abi, "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f");
var address = "0xbd8B57fdBD794f125a9D6A3A7bd8958D46201b37";
var daiExchangeAddress = "0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735";
var ethExchangeAddress = '0xc778417E063141139Fce010982780140Aa0cD5Ab';
var rinkebyRouterAddress = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D';
var router = new this.web3.eth.Contract(IRouter.abi, rinkebyRouterAddress);
var token0 = new this.web3.eth.Contract(IERC20.abi, ethExchangeAddress) //henceforth T0
var token1 = new this.web3.eth.Contract(IERC20.abi, daiExchangeAddress) //and T1
var pair = new this.web3.eth.Contract(IPair.abi,
(await factory.methods.getPair(token0.options.address, token1.options.address).call()));
const gasPrice = await web3.eth.getGasPrice()
const gasNeeded = (0.15*10**6)*2
const path = [token0.options.address,token1.options.address]
var amountIn = 999999999999;
var tx0 = {
to: token0.options.address,
gas: gasNeeded,
data: token0.methods.approve(router.options.address,amountIn).encodeABI()
}
var signedTx0 = await web3.eth.accounts.signTransaction(tx0, privKey);
var receipt0 = await web3.eth.sendSignedTransaction(signedTx0.rawTransaction)
console.log(
`Tx mined\n`+
`Tx hash: ${receipt0.transactionHash}\n`
)
const tx1 = {
to: router.options.address,
gas: gasNeeded,
data: router.methods.swapExactTokensForTokens(
amountIn,
0,
path,
address,
(Date.now() + 250)
).encodeABI()
}
var signedTx1 = await web3.eth.accounts.signTransaction(tx1, privKey);
var receipt1 = await web3.eth.sendSignedTransaction(signedTx1.rawTransaction);
}
}
As you can see, there are two transactions made. Anapprove and a swapExactTokensForTokens. The contract ABI can be found here. Some documentation on the Router02 is here. The contract itself can be found here. Thank you for any help you can provide.

try to approve to pair address, instead of router address
var tx0 = {
to: token0.options.address,
gas: gasNeeded,
data: token0.methods.approve(pair,amountIn).encodeABI()

Related

Use Aws4RequestSigner to sign PAAPI 5 Request

I'm trying to use Aws4RequestSigner in a VS2015 form to sign a search request to Amazon PAAPI.
https://www.nuget.org/packages/Aws4RequestSigner/
I get this response from the API:
{"__type":"com.amazon.paapi5#IncompleteSignatureException","Errors":[{"Code":"IncompleteSignature","Message":"The request signature did not include all of the required components. If you are using an AWS SDK, requests are signed for you automatically; otherwise, go to https://webservices.amazon.com/paapi5/documentation/sending-request.html#signing."}]}
private async void Form1_Load(object sender, EventArgs e)
{
_accessKey = "x";
_secretKey = "x";
_service = "ProductAdvertisingAPIv1";
_region = "us-east-1";
_requestUri = new Uri("https://webservices.amazon.com/paapi5/searchitems");
var payload = new
{
Keywords = "Harry",
Marketplace = "www.amazon.com",
PartnerTag = "x0d-20",
PartnerType = "Associates",
Resources = new string[] { "Images.Primary.Small", "ItemInfo.Title", "Offers.Listings.Price" },
SearchIndex = "All"
};
string jsonString = JsonConvert.SerializeObject(payload);
var content = new StringContent(jsonString, Encoding.UTF8, "application/json");
var xAmzDate = GetTimeStamp();
content.Headers.Add("content-encoding", "amz-1.0");
content.Headers.Add("x-amz-date", xAmzDate);
content.Headers.Add("x-amz-target", "com.amazon.paapi5.v1.ProductAdvertisingAPIv1.SearchItems");
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = _requestUri,
Content = content
};
request.Headers.Host = "webservices.amazon.com";
var contentType = new MediaTypeHeaderValue("application/json");
contentType.CharSet = "utf-8";
request.Content.Headers.ContentType = contentType;
var signer = new AWS4RequestSigner(_accessKey, _secretKey);
request = await signer.Sign(request, _service, _region);
try
{
var client = new HttpClient();
var response = await client.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
var error = await response.Content.ReadAsStringAsync();
}
// response.EnsureSuccessStatusCode();
txtDisplay.Text = await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException ex)
{
string error = ex.Message;
txtDisplay.Text = error;
}
}
private string GetTimeStamp()
{
return DateTime.UtcNow.ToString("yyyyMMdd\\THHmmss\\Z");
}
It could be that the headers are being added incorrectly or Aws4RequestSigner is simply outdated.

How to create signature as an input for type Vec<u8> on smart contract

I'm trying to create a signature for my function in smart contract but it return "invalid type: map, expected a sequence" error.
Here is the code:
async function onSign() {
const nearConfig = getConfig('development')
// Initialize connection to the NEAR testnet
const near = await connect(Object.assign({ deps: { keyStore: new keyStores.BrowserLocalStorageKeyStore() } }, nearConfig))
window.near = near
// Initializing Wallet based Account. It can work with NEAR testnet wallet that
// is hosted at https://wallet.testnet.near.org
window.walletConnection = new WalletConnection(near)
// Getting the Account ID. If still unauthorized, it's just empty string
window.accountId = window.walletConnection.account()
let account = window.accountId;
const realSigner = account.connection.signer
let key2 = await realSigner.keyStore.getKey(account.connection.networkId, account.accountId)
let mess = 'zxczxvzvx';
let encodedMess = str2ab(mess);
let signature = await key2.sign(encodedMess);
console.log(signature);
let a = await wallet.callMethod({
contractId: "dev-1668740733204-48404403176628",
method: "ft_transfer_call",
args: {
"receiver_id": "dev-1669022432132-58804567266197",
"amount": "0",
"memo": "None",
"msg": "create_room",
"_advisor": "dev-1669018198583-29903555965521",
"_amount_per_minute": "1",
"_room_id": "1",
"_minutes_lasts": 5,
"_signature": Buffer.from(signature.signature, 'hex'),
"_signer": "tungleanh.testnet",
}
})
}
Here is the parameters on smart contract:
&mut self,
receiver_id: AccountId,
amount: U128,
memo: Option,
msg: String,
_advisor: Option,
_amount_per_minute: Option,
_room_id: Option,
_minutes_lasts: Option,
_signature: Option<Vec>,
_signer: Option<Vec>,
How can I fix this?

PowerBI Embedded: DeleteUserAsAdminAsync returns unauthorized

Receiving an unauthorized response when trying to remove a user from a workspace (group). I'm using the .Net SDK method DeleteUserAsAdminAsync. I tried the DeleteUserInGroupAsync method with the same result. I've had no trouble retrieving groups, reports, even adding users to groups using the same authentication code shown below. I'm quite stumped.
public async Task<ResultObject> RemoveUsersFromWorkspaces(List<PowerBIWorkspace> powerBIWorkspaces)
{
// Authenticate using created credentials
AuthenticationResult authenticationResult = null;
authenticationResult = await DoAuthentication("CustomerAppRegistration");
var tokenCredentials =
new TokenCredentials(authenticationResult.AccessToken, "Bearer");
using (var client = new PowerBIClient(
new Uri("https://api.powerbi.com/"), tokenCredentials))
{
try
{
foreach (var wksp in powerBIWorkspaces)
{
// Remove the user to the workspace.
await client.Groups.DeleteUserAsAdminAsync(new Guid(wksp.WorkspaceId), wksp.UserEmail);
}
}
catch (Exception ex)
{
var errorObject = new ResultObject();
errorObject.Success = false;
errorObject.ErrorMessage = ex.Message;
return errorObject;
}
}
var resultObject = new ResultObject();
resultObject.Success = true;
resultObject.ErrorMessage = "";
return resultObject;
}
private const string AuthorityFormat = "https://login.microsoftonline.com/{0}/v2.0";
private const string MSGraphScope = "https://analysis.windows.net/powerbi/api/.default";
private async Task<AuthenticationResult> DoAuthentication(string appRegistrationSection)
{
var config = new ConfigurationBuilder()
.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
.AddJsonFile("appsettings.json").Build();
//var section = config.GetSection(nameof(AppRegistration));
var section = config.GetSection(appRegistrationSection);
var appRegistration = section.Get<AppRegistration>();
TenantID = appRegistration.TenantId;
ClientID = appRegistration.ClientId;
ClientSecret = appRegistration.ClientSecret;
IConfidentialClientApplication daemonClient;
daemonClient = ConfidentialClientApplicationBuilder.Create(ClientID)
.WithAuthority(string.Format(AuthorityFormat, TenantID))
.WithClientSecret(ClientSecret)
.Build();
AuthenticationResult authResult =
await daemonClient.AcquireTokenForClient(new[] { MSGraphScope }).ExecuteAsync();
return authResult;
}

SyntaxError: Unexpected token o in JSON at position 1. In Solidity version ^0.8.7

Hey Guys, I'm using latest solidity version 0.8.7. I'm getting this SyntaxError: Unexpected token o in JSON at position 1. Please help me regarding this problem. When I run npm run test command, it gives me this error. I really need help to get rid of this issue. That's why I'm not able to proceed further in learning solidity. Thanks a lot
**Lottery.sol File - **
pragma solidity ^0.8.7; // latest solidity version...
contract Lottery
{
address public manager;
address[] public players;
constructor()
{
manager = msg.sender;
}
function enter() public payable
{
require(msg.value > .01 ether);
players.push(msg.sender);
}
function random() private view returns (uint256)
{
return
uint256(keccak256(abi.encodePacked(block.difficulty, block.timestamp, players)));
}
function pickWinner() public restricted
{
require(msg.sender == manager);
uint256 index = random() % players.length;
uint256 amount = address(this).balance;
payable(players[index]).transfer(amount);
players = new address[](0);
}
modifier restricted()
{
require(msg.sender == manager);
_;
}
function getPlayers() public view returns (address[] memory)
{
return players;
}
}
Compile.js File -
const path = require("path");
const fs = require("fs");
const solc = require("solc");
const lotteryPath = path.resolve(__dirname, 'contracts', 'Lottery.sol');
const source = fs.readFileSync(lotteryPath, "utf8");
var input = {
language: 'Solidity',
sources: {
'lottery.sol' : {
content: source
}
},
settings: {
outputSelection: {
'*': {
'*': [ '*' ]
}
}
}
};
const output = JSON.parse(solc.compile(JSON.stringify(input))); // error on this line probably
const interface = output.contracts['lottery.sol'].lotteryPath.abi;
const bytecode = output.contracts['lottery.sol'].lotteryPath.evm.bytecode.object;
module.exports = {
interface,
bytecode,
};
lottery.test.js File
const assert = require("assert");
const ganache = require("ganache-cli");
const Web3 = require("web3");
const web3 = new Web3(ganache.provider());
const { interface, bytecode } = require("../compile");
let lottery;
let accounts;
beforeEach(async () => {
accounts = await web3.eth.getAccounts();
lottery = await new web3.eth.Contract(JSON.parse(interface)) // error on this line probably
.deploy({ data: bytecode })
.send({ from: accounts[0], gas: '1000000' });
});
describe("Lottery Contract", () => {
it("deploys a contract", () => {
assert.ok(lottery.options.address);
});
});
deploy.js File -
const HDWalletProvider = require("#truffle/hdwallet-provider");
const Web3 = require("web3");
const { interface, bytecode } = require("./compile");
const provider = new HDWalletProvider(
"*******************************************",
"https://rinkeby.infura.io/v3/********************"
);
const web3 = new Web3(provider);
const deploy = async () => {
const accounts = await web3.eth.getAccounts();
console.log("Attempting to deploy from accoutns", accounts[0]);
const result = await new web3.eth.Contract(JSON.parse(interface))
.deploy({ data: bytecode})
.send({ gas: '1000000', from: accounts[0] });
console.log("Contract deployed to", result.options.address);
};
Follow these steps.
Step 1: Check the solidity compiler version
Go to your package.json file. Under the dependencies object you will find the solc version.
Here make sure the solidity version is the same that you used in your Lottery.sol file.
If the version is not the same then please install the right version using npm
In my case, I am using ^0.8.8 in my solidity file. So I run the following command:
npm install solc#0.8.8
Step 2: Update your lottery.test.js file
In your lottery.test.js file update this line
lottery = await new web3.eth.Contract(JSON.parse(interface))
to this
lottery = await new web3.eth.Contract(interface)
Step 3: Update your deploy.js file
In your deploy.js file update this line
const result = await new web3.eth.Contract(JSON.parse(interface))
to this
const result = await new web3.eth.Contract(interface)
Also, it's a good practice to add your deployment code into a try/catch block like this:
try {
const accounts = await web3.eth.getAccounts();
console.log("Attempting to deploy from accoutns", accounts[0]);
const result = await new web3.eth.Contract(interface)
.deploy({ data: bytecode})
.send({ gas: '1000000', from: accounts[0] });
console.log("Contract deployed to", result.options.address);
} catch(error) {
console.log(error);
}
Note: Finally ensure in your deployment account you have enough ethers to test with. If you don't then get some ethers using faucets

Tron Web - Validate TransferContract error, no OwnerAccount (Tron Link)

I am developing a block chain web application using Tron Web. I have followed the document but getting below error while using tronweb.trx.sign() function,
Uncaught (in promise) class
org.tron.core.exception.ContractValidateException : Validate
TransferContract error, no OwnerAccount.
Below is my code, (I have tron link chrome extension, Node: Mainnet)
var obj = setInterval(async () => {
if (window.tronWeb && window.tronWeb.defaultAddress.base58) {
clearInterval(obj)
var tronweb = window.tronWeb
var tx = await tronweb.transactionBuilder.sendTrx('fromaddr', 10, 'toaddr');
var signedTx = await tronweb.trx.sign(tx);
var broastTx = await tronweb.trx.sendRawTransaction(signedTx);
console.log(broastTx)
}
}, 10)
Kindly check and let me know what am i missing
You should replace 'fromaddr' with 'toaddr'
var obj = setInterval(async () => {
if (window.tronWeb && window.tronWeb.defaultAddress.base58) {
clearInterval(obj)
var tronweb = window.tronWeb
var tx = await tronweb.transactionBuilder.sendTrx('toaddr', 10, 'fromaddr');
var signedTx = await tronweb.trx.sign(tx);
var broastTx = await tronweb.trx.sendRawTransaction(signedTx);
console.log(broastTx)
}
}, 10)
This line, the first and third argument are string literals and not object.
var tx = await tronweb.transactionBuilder.sendTrx('fromaddr', 10, 'toaddr');
From the docs , first and third argument are addresses.
await tronWeb.transactionBuilder.sendTrx(
toAddress,
amount,
fromAddress
);
Note: Tron addresses are available in Hex and and Base format. To convert one format to one another you can use tronWeb.address.toHex(address) or tronWeb.address.fromHex(address)