
DeFi概念介绍(三)——无常损失和滑点
上篇文章我们讲了AMM的原理,并在最后提到了无常损失这个概念。今天这篇文章就来详细介绍无常损失和滑点这两个概念。无常损失当你成为一个做交易流动池添加者(又称做市商、矿工)时,相当于是和所有交易者做一个对手盘,如果所有交易者的盈亏加在一起还是盈利状态,那这部分的利润就来自于每个做市商的无常损失。 同时无常损失不是永久性的,价格经历短暂下跌后又重新恢复,收益也会修正。 那么如何计算无常损失呢? 还是先列出AMM的核心公式:K = A * B 假设以BNB和BUSD为例:Cbnb - 池中当前BNB 的数量 为上式中的ACbusd - 池中当前BUSD 的数量 为上式中的BPbnb - bnb当前价格Pbusd - busd当前价格 恒定为1u 可省略当K恒定时,我们可以得到任何时刻池中的BNB和BUSD数量真实场景假如,我们在 1 BNB = 500 BUSD 的时候,组了一组 LP 。我们拿出了 20 个 BNB 和 10000 个 BUSD 进行 LP 流动性提供代币兑换。此时我们得到了这几个变量:并且,我们保证此时的 K 也是后续所有情况下的常数 K,即组完 LP 代币后即时生...

Gitcoin女巫检测方案Top1解读及思考
GITCOIN在两个月前举办了 OpenData 社区黑客马拉松!其中公布了三个重点领域,分别是: 女巫检测、捐款激励措施优化分析、Dune高效分析,其结果也于近日公布。 相信大家最关心的应该是女巫问题,因为今年在OP和APT的刺激下,出现了人人羡慕撸毛党,人人皆是撸毛党的盛况。 今天对女巫检测的第一名开源方案结合自身理解,进行技术向的解读,并在文末给出自己对于女巫检测的一些个人思考。相信看完这篇文章,无论是项目方还是交互者都能有所收获。 注:本文不代表官方观点,仅为个人兴趣解读。 剧透,本文较长,涉及很多技术分析,没耐心的可以直接跳转文末浏览本文总结与个人思考。由于出题者是gitcoin,其主要交互场景为捐赠。但内在逻辑在其他的场景下同样适用(transfer、mint等动作),以下将与项目方进行交互的操作统称为项目交互。方案一:批量转移和交互女巫攻击本质上是用户将资金分散到多个地址,操纵这些地址与项目方合约进行交互的过程。 那么在这个过程中则可以将整个过程拆分两个部分,分别是 批量资金转移和合约批量交互。1.1 批量转账检测选择数据批量转账最简单的就是通过智能合约的方式进行,...
零知识证明和Layer2简介
1、零知识证明简单介绍零知识证明是一方(证明者)向另一方(检验者)在不透露具体内容的条件下证明某命题的方法。 举例: 两个富翁A和B相遇,两人的资产都在1-10亿之间,要如何在不告诉对方自己具体财富的情况下,得出对方是否比自己有钱?区块链中的零知识证明:其实大家可能会疑惑,为什么会用到零知识证明,那其实。在区块链机制中,想要去证明自己有存储某个东西的时候。他其实是不会把这个东西全部发给你来证明?比如说存储了一部电影我,可能不会把整个电影发给你了他,会有一种证明机制去,证明里面的某一块或者是某个东西他是有的,通过提交某个证明去给到系统,系统知道你有存这个东西这种就是其实就是零知识证明的一种,就是不公布具体内容,但是证明某个事情。例如银行贷款必须提交资产证明,通过零知识,无需提供银行房本,住址这些资料。2、Layer2简单介绍起源Layer2的诞生是为了解决以太坊主网拥堵及昂贵的问题,在Eth2.0完成之前保持住以太坊上生态霸主的地位。 广泛层面上,Layer2包含所有和以太坊主链有桥接的项目,包含像Polygon这类几乎独立的区块链; 狭义层面,指的是指以以太坊主网作为最终状态记录...
<100 subscribers

DeFi概念介绍(三)——无常损失和滑点
上篇文章我们讲了AMM的原理,并在最后提到了无常损失这个概念。今天这篇文章就来详细介绍无常损失和滑点这两个概念。无常损失当你成为一个做交易流动池添加者(又称做市商、矿工)时,相当于是和所有交易者做一个对手盘,如果所有交易者的盈亏加在一起还是盈利状态,那这部分的利润就来自于每个做市商的无常损失。 同时无常损失不是永久性的,价格经历短暂下跌后又重新恢复,收益也会修正。 那么如何计算无常损失呢? 还是先列出AMM的核心公式:K = A * B 假设以BNB和BUSD为例:Cbnb - 池中当前BNB 的数量 为上式中的ACbusd - 池中当前BUSD 的数量 为上式中的BPbnb - bnb当前价格Pbusd - busd当前价格 恒定为1u 可省略当K恒定时,我们可以得到任何时刻池中的BNB和BUSD数量真实场景假如,我们在 1 BNB = 500 BUSD 的时候,组了一组 LP 。我们拿出了 20 个 BNB 和 10000 个 BUSD 进行 LP 流动性提供代币兑换。此时我们得到了这几个变量:并且,我们保证此时的 K 也是后续所有情况下的常数 K,即组完 LP 代币后即时生...

Gitcoin女巫检测方案Top1解读及思考
GITCOIN在两个月前举办了 OpenData 社区黑客马拉松!其中公布了三个重点领域,分别是: 女巫检测、捐款激励措施优化分析、Dune高效分析,其结果也于近日公布。 相信大家最关心的应该是女巫问题,因为今年在OP和APT的刺激下,出现了人人羡慕撸毛党,人人皆是撸毛党的盛况。 今天对女巫检测的第一名开源方案结合自身理解,进行技术向的解读,并在文末给出自己对于女巫检测的一些个人思考。相信看完这篇文章,无论是项目方还是交互者都能有所收获。 注:本文不代表官方观点,仅为个人兴趣解读。 剧透,本文较长,涉及很多技术分析,没耐心的可以直接跳转文末浏览本文总结与个人思考。由于出题者是gitcoin,其主要交互场景为捐赠。但内在逻辑在其他的场景下同样适用(transfer、mint等动作),以下将与项目方进行交互的操作统称为项目交互。方案一:批量转移和交互女巫攻击本质上是用户将资金分散到多个地址,操纵这些地址与项目方合约进行交互的过程。 那么在这个过程中则可以将整个过程拆分两个部分,分别是 批量资金转移和合约批量交互。1.1 批量转账检测选择数据批量转账最简单的就是通过智能合约的方式进行,...
零知识证明和Layer2简介
1、零知识证明简单介绍零知识证明是一方(证明者)向另一方(检验者)在不透露具体内容的条件下证明某命题的方法。 举例: 两个富翁A和B相遇,两人的资产都在1-10亿之间,要如何在不告诉对方自己具体财富的情况下,得出对方是否比自己有钱?区块链中的零知识证明:其实大家可能会疑惑,为什么会用到零知识证明,那其实。在区块链机制中,想要去证明自己有存储某个东西的时候。他其实是不会把这个东西全部发给你来证明?比如说存储了一部电影我,可能不会把整个电影发给你了他,会有一种证明机制去,证明里面的某一块或者是某个东西他是有的,通过提交某个证明去给到系统,系统知道你有存这个东西这种就是其实就是零知识证明的一种,就是不公布具体内容,但是证明某个事情。例如银行贷款必须提交资产证明,通过零知识,无需提供银行房本,住址这些资料。2、Layer2简单介绍起源Layer2的诞生是为了解决以太坊主网拥堵及昂贵的问题,在Eth2.0完成之前保持住以太坊上生态霸主的地位。 广泛层面上,Layer2包含所有和以太坊主链有桥接的项目,包含像Polygon这类几乎独立的区块链; 狭义层面,指的是指以以太坊主网作为最终状态记录...
Share Dialog
Share Dialog


AIshiba作为arb上一个比较早期的土狗NFT,毫不夸张的说引燃了arb上的NFT潮流。floor price曾一度最高达到0.04e,但是现在已经跌倒了0.004e(大概8刀)。

这就是妥妥的土狗项目,官网做的也是极其简陋,连白皮书都没有,只有路线图。但是没办法,赶上了风口,猪都能飞上天,赶上arb的aidog热度。
并且在今天凌晨进行nft空投发币,空投规则是按照快照时的地址NFT个数计算,即NFT拥有数量越多,空投claim的代币越多,nft空投上限10个,超过按照10个计算。
谁知道发币出现bug,导致科学家发现漏洞,单号直接mint最大量的token 17700000000000 * 10 ** 6 。最高点卖出大概1e+。 代币k线

核心原因是项目方利用Merkle Tree发放 空投token,但是本应该在后台的保存了全量地址被项目方放在了前端,并且未做任何混淆代码的保护处理。导致proof被轻易计算得到。(了解原理可参阅文末参考文献)
只需要在官网按 F12 整个代码一览无余:

merkleProof.js
const { WHITELIST_ADDRESS } = require("./whitelist_Address")
const keccak256 = require("keccak256")
const { MerkleTree } = require("merkletreejs")
const addressLeaves = WHITELIST_ADDRESS.map(x => keccak256(x))
const merkleTree = new MerkleTree(addressLeaves, keccak256, {
sortPairs : true
})
const rootHash = merkleTree.getHexRoot()
module.exports = { merkleTree, rootHash }
并且调用合约的方法,传入参数也非常清晰:

index.js
const handleClaimForNfts = async () => {
try {
const signer = await getProviderOrSigner(true);
const userAddress = signer.getAddress();
const aiShibaContract = new Contract(
AISHIBA_CONTRACT_ADDRESS,
AISHIBA_CONTRACT_ABI,
signer
);
const txn = await aiShibaContract.claimTokensForNft(merkleProof, nftBalance);
await txn.wait();
console.log("txn", txn);
console.log("txn", "successful");
} catch (error) {
console.error(error);
}
};
可以看到调用了合约的 claimTokensForNft() 方法,传入了merkleProof 和 nftBalance 两个变量,nftBalance 代表着快照拥有NFT的数量。
其中merkleProof 只需要 用下列方法 merkleTree.getHexProof(_leaf) 即可获取
index.js
const getProof = async () => {
const signer = await getProviderOrSigner(true);
const _userAddress = await signer.getAddress();
const _leaf = keccak256(_userAddress);
const _merkleProof = merkleTree.getHexProof(_leaf);
setUserAddress(_userAddress);
setMerkleProof(_merkleProof);
};
再看一下领取的合约代码
function claimTokensForNft(bytes32[] calldata proof, uint256 _amount) public claimIsLive {
bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
require(MerkleProof.verify(proof, merkleRootNFT, leaf), "Wallet not eligible to claim");
require(_amount > 0, "You do not own any tokens");
require(!hasClaimedNFT[msg.sender], "You have claimed your Tokens");
uint256 amountOfTokensToClaim;
if(_amount<= 2) {
amountOfTokensToClaim = tier1Claim;
} else if( _amount > 2 && _amount <= 4){
amountOfTokensToClaim = tier2Claim;
} else if(_amount > 4 && _amount <= 9) {
amountOfTokensToClaim = tier3Claim;
} else if(_amount >= 10) {
amountOfTokensToClaim = tier4Claim;
}
totalTokensClaimed += amountOfTokensToClaim;
hasClaimedNFT[msg.sender] = true;
require(tokenContract.transfer(msg.sender, amountOfTokensToClaim), "Transfer failed");
emit HasClaimedNFT(msg.sender, amountOfTokensToClaim);
}
_amount 即为nft的数量,合约按照 _amount 数量进行空投token。
_amount<=2 空投代币 1475000000000 * 10 ** 6
2<_amount<=4 空投代币 3375000000000 * 10 ** 6
4<_amount<=9 空投代币 7750000000000 * 10 ** 6
_amount>=10 空投代币 17700000000000 * 10 ** 6
合约中没有对_amount的校验操作,即使你的钱包地址拥有1个nft(即拥有白名单权限),只要Merkle tree 验证成功,_amount传入10或者更大值也能mint 到单地址最高数量代币,即 17700000000000 * 10 ** 6 。
大概有1800个地址领取了空投,绝大部分都是科学家

项目方发现了不对劲,在凌晨的00:45已经关闭了合约,并在接下来转走了合约中所有token。
据传言(道听途说):背后的项目方是大学生,整个寝室一起出动一起赚钱,如果真是这样,现在这大学生还真他娘的敢想敢干,割起韭菜来也是毫不手软。
可惜 螳螂捕蝉,黄雀在后,项目成了科学家的提款机,最可怜的还是那些真金白银在DEX和CEX中买Token的韭菜们。
不玩土狗的我 看着大佬们的卖币截图和聊天记录,又一次感慨道:
别人赚钱如呼吸般简单,自己赚钱如吃屎般困难。
本人推特:@coolberwin_eth
文章参考:
Merkle tree的 原理: WTF Ethers极简入门: MerkleTree脚本
AIshiba作为arb上一个比较早期的土狗NFT,毫不夸张的说引燃了arb上的NFT潮流。floor price曾一度最高达到0.04e,但是现在已经跌倒了0.004e(大概8刀)。

这就是妥妥的土狗项目,官网做的也是极其简陋,连白皮书都没有,只有路线图。但是没办法,赶上了风口,猪都能飞上天,赶上arb的aidog热度。
并且在今天凌晨进行nft空投发币,空投规则是按照快照时的地址NFT个数计算,即NFT拥有数量越多,空投claim的代币越多,nft空投上限10个,超过按照10个计算。
谁知道发币出现bug,导致科学家发现漏洞,单号直接mint最大量的token 17700000000000 * 10 ** 6 。最高点卖出大概1e+。 代币k线

核心原因是项目方利用Merkle Tree发放 空投token,但是本应该在后台的保存了全量地址被项目方放在了前端,并且未做任何混淆代码的保护处理。导致proof被轻易计算得到。(了解原理可参阅文末参考文献)
只需要在官网按 F12 整个代码一览无余:

merkleProof.js
const { WHITELIST_ADDRESS } = require("./whitelist_Address")
const keccak256 = require("keccak256")
const { MerkleTree } = require("merkletreejs")
const addressLeaves = WHITELIST_ADDRESS.map(x => keccak256(x))
const merkleTree = new MerkleTree(addressLeaves, keccak256, {
sortPairs : true
})
const rootHash = merkleTree.getHexRoot()
module.exports = { merkleTree, rootHash }
并且调用合约的方法,传入参数也非常清晰:

index.js
const handleClaimForNfts = async () => {
try {
const signer = await getProviderOrSigner(true);
const userAddress = signer.getAddress();
const aiShibaContract = new Contract(
AISHIBA_CONTRACT_ADDRESS,
AISHIBA_CONTRACT_ABI,
signer
);
const txn = await aiShibaContract.claimTokensForNft(merkleProof, nftBalance);
await txn.wait();
console.log("txn", txn);
console.log("txn", "successful");
} catch (error) {
console.error(error);
}
};
可以看到调用了合约的 claimTokensForNft() 方法,传入了merkleProof 和 nftBalance 两个变量,nftBalance 代表着快照拥有NFT的数量。
其中merkleProof 只需要 用下列方法 merkleTree.getHexProof(_leaf) 即可获取
index.js
const getProof = async () => {
const signer = await getProviderOrSigner(true);
const _userAddress = await signer.getAddress();
const _leaf = keccak256(_userAddress);
const _merkleProof = merkleTree.getHexProof(_leaf);
setUserAddress(_userAddress);
setMerkleProof(_merkleProof);
};
再看一下领取的合约代码
function claimTokensForNft(bytes32[] calldata proof, uint256 _amount) public claimIsLive {
bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
require(MerkleProof.verify(proof, merkleRootNFT, leaf), "Wallet not eligible to claim");
require(_amount > 0, "You do not own any tokens");
require(!hasClaimedNFT[msg.sender], "You have claimed your Tokens");
uint256 amountOfTokensToClaim;
if(_amount<= 2) {
amountOfTokensToClaim = tier1Claim;
} else if( _amount > 2 && _amount <= 4){
amountOfTokensToClaim = tier2Claim;
} else if(_amount > 4 && _amount <= 9) {
amountOfTokensToClaim = tier3Claim;
} else if(_amount >= 10) {
amountOfTokensToClaim = tier4Claim;
}
totalTokensClaimed += amountOfTokensToClaim;
hasClaimedNFT[msg.sender] = true;
require(tokenContract.transfer(msg.sender, amountOfTokensToClaim), "Transfer failed");
emit HasClaimedNFT(msg.sender, amountOfTokensToClaim);
}
_amount 即为nft的数量,合约按照 _amount 数量进行空投token。
_amount<=2 空投代币 1475000000000 * 10 ** 6
2<_amount<=4 空投代币 3375000000000 * 10 ** 6
4<_amount<=9 空投代币 7750000000000 * 10 ** 6
_amount>=10 空投代币 17700000000000 * 10 ** 6
合约中没有对_amount的校验操作,即使你的钱包地址拥有1个nft(即拥有白名单权限),只要Merkle tree 验证成功,_amount传入10或者更大值也能mint 到单地址最高数量代币,即 17700000000000 * 10 ** 6 。
大概有1800个地址领取了空投,绝大部分都是科学家

项目方发现了不对劲,在凌晨的00:45已经关闭了合约,并在接下来转走了合约中所有token。
据传言(道听途说):背后的项目方是大学生,整个寝室一起出动一起赚钱,如果真是这样,现在这大学生还真他娘的敢想敢干,割起韭菜来也是毫不手软。
可惜 螳螂捕蝉,黄雀在后,项目成了科学家的提款机,最可怜的还是那些真金白银在DEX和CEX中买Token的韭菜们。
不玩土狗的我 看着大佬们的卖币截图和聊天记录,又一次感慨道:
别人赚钱如呼吸般简单,自己赚钱如吃屎般困难。
本人推特:@coolberwin_eth
文章参考:
Merkle tree的 原理: WTF Ethers极简入门: MerkleTree脚本
No comments yet