惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Privacy International News Feed
Hacker News - Newest:
Hacker News - Newest: "LLM"
Application and Cybersecurity Blog
Application and Cybersecurity Blog
N
News and Events Feed by Topic
Hacker News: Ask HN
Hacker News: Ask HN
V2EX - 技术
V2EX - 技术
L
LINUX DO - 最新话题
Google Online Security Blog
Google Online Security Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Stack Overflow Blog
Stack Overflow Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
P
Proofpoint News Feed
A
Arctic Wolf
Forbes - Security
Forbes - Security
Spread Privacy
Spread Privacy
Security Latest
Security Latest
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
CERT Recently Published Vulnerability Notes
Latest news
Latest news
AWS News Blog
AWS News Blog
M
MIT News - Artificial intelligence
GbyAI
GbyAI
V
Visual Studio Blog
T
The Blog of Author Tim Ferriss
有赞技术团队
有赞技术团队
Help Net Security
Help Net Security
博客园 - Franky
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
S
Schneier on Security
S
SegmentFault 最新的问题
Microsoft Security Blog
Microsoft Security Blog
Y
Y Combinator Blog
PCI Perspectives
PCI Perspectives
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园_首页
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Palo Alto Networks Blog
SecWiki News
SecWiki News
TaoSecurity Blog
TaoSecurity Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
K
Kaspersky official blog
G
Google Developers Blog
H
Hacker News: Front Page
T
Tailwind CSS Blog
aimingoo的专栏
aimingoo的专栏
博客园 - 叶小钗
T
Troy Hunt's Blog
F
Full Disclosure
T
Threat Research - Cisco Blogs

高金的博客

人机协作逆向:用 AI + Frida 打通微信 4.1.8 macOS 数据库密钥提取 情绪价值与求真:如何平衡与应对? friend_tech 套利到底有多卷 无公网ip,无服务器实现内网穿透 植物挖矿 浏览器环境检测 加密、编码相关知识汇总 使用tensorflow识别验证码 POW与反爬虫 appium 安卓无法点击搜索框解决办法 知乎直播弹幕抓取与解析 知乎直播套利分析 1000刀+的羊毛在等你 如何创建一个完全匿名的EOS、ETH账号 如何通过技术手段证明"我"没有去过武汉 XUNTA 季度报告 玩游戏不如CX,JUSTGAME邀请分析(内附元数据) 如何在conflux上部署合约 程序员找对象聚合平台-xunta.today EOS 1.8 bidname的漏洞分析
friend_tech 第一笔交易只能买 1 个key?
Gao JIn · 2023-09-19 · via 高金的博客

背景

群里有人说friend tech 第一笔交易只能自己购买1笔?

我当时就反驳了他,毕竟我也算看过 friend tech 合约代码的人,合约没有限制只能买 1 笔啊

废话少说,直接看代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function buyShares(address sharesSubject, uint256 amount) public payable {
uint256 supply = sharesSupply[sharesSubject];
require(supply > 0 || sharesSubject == msg.sender, "Only the shares' subject can buy the first share");
uint256 price = getPrice(supply, amount);
uint256 protocolFee = price * protocolFeePercent / 1 ether;
uint256 subjectFee = price * subjectFeePercent / 1 ether;
require(msg.value >= price + protocolFee + subjectFee, "Insufficient payment");
sharesBalance[sharesSubject][msg.sender] = sharesBalance[sharesSubject][msg.sender] + amount;
sharesSupply[sharesSubject] = supply + amount;
emit Trade(msg.sender, sharesSubject, true, amount, price, protocolFee, subjectFee, supply + amount);
(bool success1,) = protocolFeeDestination.call{value: protocolFee}("");
(bool success2,) = sharesSubject.call{value: subjectFee}("");
require(success1 && success2, "Unable to send funds");
}

一看代码很简单,唯一限制的就这一句

require(supply > 0 || sharesSubject == msg.sender, "Only the shares' subject can buy the first share");

这句话的意思 新注册用户,只能自己买入第一笔. 也没有限制买多少key啊…

没那么简单

那别人为啥还言之凿凿说确实只能买 1 个key 呢?

严谨一点直接用forge模拟买买看就知道了.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import {TestHarness} from "../../TestHarness.sol";

interface iFriendtech {
function buyShares(address sharesSubject, uint256 amount) external payable;
}

contract fuck_friend_tech is TestHarness {
iFriendtech friendtech = iFriendtech(0xCF205808Ed36593aa40a44F10c7f7C2F67d4A4d4);

function setUp() external {
cheat.createSelectFork("base", 4_119_770);
cheat.deal(address(this), 100 ether);
}

function test_attack() external {
friendtech.buyShares{value: 100 ether}(address(this), 2);
}

receive() external payable {}
}

你别说,还真失败了…报错为 [FAIL. Reason: Arithmetic over/underflow] test_attack() (gas: 3252)

显示溢出报错.肯定是哪里做运算出错了

再回头看buyShares的代码,唯一有疑点的地方就是getPrice

1
2
3
4
5
6
7
8
9
function getPrice(uint256 supply, uint256 amount) public view returns (uint256) {
uint256 sum1 = supply == 0 ? 0 : (supply - 1) * (supply) * (2 * (supply - 1) + 1) / 6;
uint256 sum2 = supply == 0 && amount == 1
? 0
: (supply - 1 + amount) * (supply + amount) * (2 * (supply - 1 + amount) + 1) / 6;

uint256 summation = sum2 - sum1;
return summation * 1 ether / 16_000;
}

出现问题在sum2… supply-1+amount这边就出错了…毕竟 solidity 语言有点傻,0-1=-1就直接溢出了…

好吧,原来不能第一次买多个的原因是 团队写 bug 了…改正也很简单,先+后-就可以了,这也算 solidity 开发常见的问题了,要先加后减,先乘后除

(supply - 1 + amount) * (supply + amount) * (2 * (supply - 1 + amount) + 1) / 6;
(supply + amount - 1) * (supply + amount) * (2 * (supply + amount - 1) + 1) / 6;

getPrice 分析

再回头看getPrice的代码.
估计第一眼看过去的都会比较迷糊,这到底是干啥了…当然数学大神一下就能看出来这是平方和公式

我们可以借助 ChatGPT

1
2
3
4
5
6
7
8
9
10
11
12
13
Q: (supply - 1) * (supply) * (2 * (supply - 1) + 1) / 6 这是什么公式?

A:
这个公式是用来计算一个整数变量(通常表示为"supply")的平方和平方和的一种表示方式。公式的具体步骤如下:

1. 先将"supply"的值减去1,即"(supply - 1)"。
2. 然后将该值与"supply"相乘,即"(supply - 1) * supply"。
3. 接下来,将2乘以"(supply - 1)",即"2 * (supply - 1)"。
4. 将上一步骤的结果加1,即"2 * (supply - 1) + 1"。
5. 最后,将前三步骤的结果相乘,并将其除以6,即"(supply - 1) * supply * (2 * (supply - 1) + 1) / 6"。

这个公式可以用来计算一系列连续整数的平方和,其中"supply"代表整数的上限。这种形式的平方和通常在数学和统计学中有多种应用,比如计算方差、概率分布等。

知道这是平方求和公式就简单了,这段代码就很好理解了
((supply-1+amount)的平方和 - (supply-1)的平方和) / 16000


本文作者:高金
本文地址https://igaojin.me/2023/09/19/friend-tech-第一笔交易只能买-1-个key/
版权声明:转载请注明出处!

推荐文章