Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Don't know Solidity? Don't worry.
https://rpc.shadow.xyz/ethereum/mainnet/v1/<fork_id>/<version>curl https://rpc.shadow.xyz/ethereum/mainnet/v1/<fork_id>/<version> \
-X POST \
-H "Content-Type: application/json" \
-H "X-SHADOW-API-KEY: <API_KEY>" \
--data '{
"method": "eth_getLogs",
"params": [{
"fromBlock": "safe",
"toBlock": "latest",
"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"topics": []
}],
"id": 1,
"jsonrpc": "2.0"
}'https://app.tryshadow.xyz/explorer/addresses/0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640?project_id=a8a8a8a8-3a3a-423e-8b8b-b0b0b0b0b0b0
This 5 minute tutorial will walk you through steps to create a shadow fork of Ethereum Mainnet, add a shadow event to a contract, and retrieve its data.
https://app.shadow.xyz/?project_id=fc6ee70a-6f14-4a99-81db-6bd96226b95fevent HelloWorld(string message);HelloWorld("Emitting my first shadow event");curl https://rpc.shadow.xyz/ethereum/mainnet/v1/<fork_id>/<version> \
-X POST \
-H "Content-Type: application/json" \
-H "X-SHADOW-API-KEY: <API_KEY>" \
--data '{
"method": "eth_getLogs",
"params": [{
"fromBlock": "safe",
"toBlock": "latest",
"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"topics": []
}],
"id": 1,
"jsonrpc": "2.0"
}'



Your shadow fork has immutable versioning so you can safely deploy changes without disrupting previously running jobs.
Learn how to authenticate your requests to Shadow.











curl https://rpc.shadow.xyz/ethereum/mainnet/v1/<FORK>/<VERSION> \
-X POST \
-H "Content-Type: application/json" \
-H "X-SHADOW-API-KEY: <YOUR-API-KEY>" \
--data '{"method":"eth_blockNumber","params":[],"id":1,"jsonrpc":"2.0"}'
Set up a fully managed data pipeline to export data to a GCS / S3 bucket in a one-off or recurring fashion.
Set up a fully managed data pipeline to upload data to Dune in a one-off or recurring fashion.
Set up a fully managed data pipeline to stream data into your Postgres database in real-time.





function transferFromForLien(address from, address to, uint256 amount, uint256 lienId, Lien calldata lien, string calldata annotation) external returns (bool) {
bool result = transferFrom(from, to, amount);
emit TransferForLien(from, to, amount, lienId, lien, annotation);
return result;
}event TransferForLien(
address indexed from,
address indexed to,
uint256 amount,
uint256 lienId,
Lien lien,
string annotation
);
User ---- tx ---> Proxy ----------> Implementation_v0
|
------------> Implementation_v1
|
------------> Implementation_v2struct TransferMetadata {
uint256 balanceBefore;
uint256 balanceAfter;
int256 percentChange;
}
event TransferWithMetadata(
address from,
address to,
uint256 amount,
TransferMetadata fromMetadata,
TransferMetadata toMetadata
);function _transfer(
address from,
address to,
uint256 value
) internal override {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
require(
value <= _balanceOf(from),
"ERC20: transfer amount exceeds balance"
);
uint256 fromBalanceBefore = _balanceOf(from);
uint256 fromBalanceAfter = _balanceOf(from).sub(value);
int256 fromPercentChange = -int256(value * uint256(10)**uint256(6) / fromBalanceBefore);
TransferMetadata memory fromTransferMetadata = TransferMetadata({
balanceBefore: fromBalanceBefore,
balanceAfter: fromBalanceAfter,
percentChange: fromPercentChange
});
uint256 toBalanceBefore = _balanceOf(to);
uint256 toBalanceAfter = _balanceOf(to).add(value);
int256 toPercentChange = int256(value * uint256(10)**uint256(6) / toBalanceBefore);
TransferMetadata memory toTransferMetadata = TransferMetadata({
balanceBefore: toBalanceBefore,
balanceAfter: toBalanceAfter,
percentChange: toPercentChange
});
emit TransferWithMetadata(from, to, value, fromTransferMetadata, toTransferMetadata);
_setBalance(from, _balanceOf(from).sub(value));
_setBalance(to, _balanceOf(to).add(value));
emit Transfer(from, to, value);
}struct OrderDetails {
address maker;
address taker;
address makerToken;
address takerToken;
uint256 takerTokenFilledAmount;
uint256 makerTokenFilledAmount;
uint256 orderAmountUsd;
}
event OrderFilledDetails(OrderDetails orderDetails);uint256 orderAmountUsd = getOrderAmountUsd(order.makerAsset, order.takerAsset, actualMakingAmount, actualTakingAmount);
OrderDetails memory orderDetails = OrderDetails({
maker: order.maker,
taker: order.receiver,
makerToken: order.makerAsset,
takerToken: order.takerAsset,
takerTokenFilledAmount: actualTakingAmount,
makerTokenFilledAmount: actualMakingAmount,
orderAmountUsd: orderAmountUsd
});
emit OrderFilledDetails(orderDetails);function getOrderAmountUsd(address makerToken, address takerToken, uint256 makerTokenAmount, uint256 takerTokenAmount) internal returns (uint256 orderAmountUsd) {
if (takerToken == address(_WETH)) {
orderAmountUsd = takerTokenAmount * uint256(getPriceETH()) * 1e6 / 1e18 / 1e8;
} else if (makerToken == address(_WETH)) {
orderAmountUsd = makerTokenAmount * uint256(getPriceETH()) * 1e6 / 1e18 / 1e8;
} else if (isStable(makerToken)) {
orderAmountUsd = makerTokenAmount * 1e6;
} else if (isStable(takerToken)) {
orderAmountUsd = takerTokenAmount * 1e6;
}
bool isStable = isStable(makerToken) || isStable(takerToken);
}
function isStable(address token) internal returns (bool) {
if (
token == 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 || // USDC
token == 0xdAC17F958D2ee523a2206206994597C13D831ec7 || // USDT
token == 0x6B175474E89094C44Da98b954EedeAC495271d0F // DAI
) {
return true;
}
return false;
}
// Get the current price of ETH from Chainlink's ETH/USD oracle (8 decimals)
function getPriceETH() internal view returns (int256) {
AggregatorV3Interface dataFeed = AggregatorV3Interface(
0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
);
(, int256 answer, , , ) = dataFeed.latestRoundData();
return answer;
}Don't know Solidity? Don't worry.




I have created a developer platform called Shadow, that enables you to spin up a fork of Ethereum mainnet that tracks actual mainnet transactions in real time.
On Shadow, you can add custom events, view functions, and storage variables to any verified contract without any gas, contract size, or deployment constraints.
The way it works is the user modifies the contract source code of the original contract, and adds code to declare new events and emit those events. Shadow forks run on a slightly modified version of the EVM, that has no gas costs or contract size limitations. Shadow compiles the modified "shadow contracts", and then deploys the bytecode at the same contract address as the address on mainnet. Shadow also ensures that we don't run into out of gas errors and that the shadow fork ETH and token balances are always in sync with mainnet. When mainnet transactions are executed on the shadow fork, the custom "shadow events" are emitted on the shadow fork.
The codebase you see is one that I'm modifying, and will deploy on a shadow fork. Your task is to guide me in writing modified shadow contracts. I want you to answer my questions in concise terms, always review the entire codebase in detail before answering, and provide specific examples with code snippets. When I ask you to write me code, it should always to be code that I can successfully compile and deploy as a shadow contract. Include comments to explain what you are doing, and double check your work. Do not use pseudocode.
When providing answers and code that I can use, always double check to review the entire function scope and ensure that it will not run into a stack too deep Solidity compiler error. Use helper functions and structs to help avoid the stack too deep error. When making recommendations for code changes, always seek to minimize code changes to the original parts of the smart contracts. Never add new function parameters to the original functions in the contract, or add completely new files to the contract. Be sure to double check all the other files within a contract that might need a modification as a result of a modifications you recommend.
















