- vừa được xem lúc

PHÂN TÍCH VỤ HACK 2.1 TRIỆU $ TRÊN GYM NETWORK

0 0 37

Người đăng: ChainZoom Security

Theo Viblo Asia

Gym Network vẫn bị hack cho dù đã được audit bởi 2 cái tên lớn là Certik và PeckShield

ChainZoom đã điều tra và tổng hợp logic của tất cả module của GymNetwork trước khi bị hack tại repos này.

2.png

Giới thiệu

Gym Network, một nền tảng được giới thiệu là tối ưu hóa lãi suất dựa trên hình thức farming cho user, vừa bị hack $2.1M vào ngày 8 tháng 6 vừa qua. Vụ việc khiến token GYMNET giảm từ $0.2 về $0.026, hiện tại token này đã phục hồi về mức giá $0.08

Diễn biến sự việc

Jun-08-2022 05:18:03 AM +UTC

Hacker tấn công vào module GymSinglePool thông qua contract mà anh ta tự code

=> Kết quả của transaction này là hacker được ghi nhận đã deposit rất nhiều $GYMNET vào GymSinglePool mặc dù thực tế anh ta chẳng deposit một đồng $GYMNET nào.

Jun-08-2022 05:18:45 AM +UTC

Hacker withdraw 8,000,000 GYMNET từ GymSinglePool về contract của mình. Transaction tại đây.

Jun-08-2022 05:18:45 AM +UTC

Hacker chuyển 320,000 GYMNET đến ví 0xef6afbb3e43a1289bd6b96252d372058106042f6, 480,000 GYMNET đến ví 0x7e8413065775e50b0b0717c46118b2e6c87e960a, đồng thời swap 7,200,000 GYMNET còn lại lấy hơn 3300 BNB. Transaction tại đây.

Vậy Hacker đã tấn công GymSinglePool như thế nào?

Contract GymSinglePool thực chất là một Proxy, trước khi bị tấn công, nó thực thi theo logic được triển khai tại contract này

Có thể xem code tại đây.

Về cơ bản GymSinglePool cho phép user farm theo block, nó là logic của sushi farm được mở rộng thêm chức năng lựa chọn lockingPeriods và levels cùng với tối ưu hóa lãi suất thông qua một loạt các modules như: GymAccountant, GymMLM, GymVaultBank, LiquidityProvider, NetGymFarming.

Chúng ta cùng nhìn vào hàm deposit của GymSimglePool:

/**
* @notice Deposit in given pool
* @param _depositAmount: Amount of want token that user wants to deposit
*/
function deposit( uint256 _depositAmount, uint8 _periodId, uint256 _referrerId, bool isUnlocked
) external { require(isPoolActive, "Contract is not running yet"); IGymMLM(relationship).addGymMLM(msg.sender, _referrerId); _deposit(_depositAmount, _periodId, isUnlocked);
}

IGymMLM().addGymMLM()chỉ là một bước lưu lại thông tin user tham gia vào Pool thông qua sự giới thiệu bởi một user khác.

 function _deposit( uint256 _depositAmount, uint8 _periodId, bool _isUnlocked ) private { UserInfo storage user = userInfo[msg.sender]; IERC20Upgradeable token = IERC20Upgradeable(tokenAddress); PoolInfo storage pool = poolInfo; updatePool(); uint256 period = months[_periodId]; uint256 lockTimesamp = DateTime.addMonths( block.timestamp, months[_periodId] ); uint256 burnTokensAmount = 0; if (!_isUnlocked) { burnTokensAmount = (_depositAmount * 4) / 100; totalBurntInSinglePool += burnTokensAmount; IERC20Burnable(tokenAddress).burnFrom(msg.sender, burnTokensAmount); } uint256 amountToDeposit = _depositAmount - burnTokensAmount; token.safeTransferFrom(msg.sender, address(this), amountToDeposit); uint256 UsdValueOfGym = ((amountToDeposit * getPrice()) / 1e18) / 1e18; user.totalDepositTokens += amountToDeposit; user.totalDepositDollarValue += UsdValueOfGym; totalGymnetLocked += amountToDeposit; if (_isUnlocked) { totalGymnetUnlocked += amountToDeposit; period = 0; lockTimesamp = DateTime.addSeconds( block.timestamp, months[_periodId] ); } uint256 rewardDebt = (amountToDeposit * (pool.accRewardPerShare)) / (1e18); UserDeposits memory depositDetails = UserDeposits({ depositTokens: amountToDeposit, depositDollarValue: UsdValueOfGym, stakePeriod: period, depositTimestamp: block.timestamp, withdrawalTimestamp: lockTimesamp, rewardsGained: 0, is_finished: false, rewardsClaimt: 0, rewardDebt: rewardDebt }); user_deposits[msg.sender].push(depositDetails); user.depositId = user_deposits[msg.sender].length; for (uint256 i = 0; i < levels.length; i++) { if (user.totalDepositDollarValue >= levels[i]) { user.level = i; } } emit Deposit(msg.sender, _depositAmount, _periodId); }

Ở hàm_deposit(): (từ dòng 386 đến 450)

  • updatePool(), sẽ khá quen thuộc với những ai đã tìm hiểu về sushi farm
  • token.safeTransferFrom(msg.sender, address(this), amountToDeposit), chuyển tiền từ user về
  • các logic tính toán timestamp và cập nhật thông tin cho user

Ở đây bước quan trọng nhất là token.safeTransferFrom(msg.sender, address(this), amountToDeposit), để đảm bảo user thực sự deposit vào pool.

Sau khi deposit(), user có thể withdraw() dựa trên thông tin đã được ghi nhận ở bước deposit, từ dòng 528-585.

function withdraw(uint256 _depositId) external { require(_depositId >= 0, "Value is not specified"); updatePool(); _withdraw(_depositId);
}

Có thêm một kiểu deposit nữa ở hàm depositFromOtherContract()

/** * @notice Deposit in given pool * @param _depositAmount: Amount of want token that user wants to deposit */ function depositFromOtherContract( uint256 _depositAmount, uint8 _periodId, bool isUnlocked, address _from ) external { require(isPoolActive, "Contract is not running yet"); _autoDeposit(_depositAmount, _periodId, isUnlocked, _from); }

Ở hàm _autoDeposit() cũng có:

  • updatePool()
  • các logic tính toán và cập nhật thông tin cho user

Nhưng token.safeTransferFrom() đâu? tại sao không chuyển tiền từ user về pool mà pool lại tự approve cho chính nó tiêu tiền của chính nó? (dòng 466)

token.approve(address(this), _depositAmount);

Hacker đã lợi dụng điều này để tấn công, anh ta không hề deposit một đồng GYMNET nào nhưng lại được ghi nhận đã deposit 8,000,000 GYMNET vào pool, sau đó anh ta withdraw 8,000,000 GYMNET ra và bán tháo nó.

Điều này khiến chúng ta đặt ra rất nhiều nghi vấn. Liệu vụ hack là do sự bất cẩn của Gym Netwwork, hay đây là kịch bản đã được sắp xếp sẵn?

Bình luận

Bài viết tương tự

- vừa được xem lúc

[Blockchain] Road to Bitcoin

. Chắc mọi người hẳn đã không còn xa lạ gì với anh chàng tỷ phú đã ném vỡ cửa kính ô tô nhà mình cùng với siêu năng lực điều khiển vật giá chỉ bằng lời nói, người đã đẩy định giá Bitcoin trên thị trường vượt ngưỡng 50K dolar/coin với những bài twitter để đời . .

0 0 61

- vừa được xem lúc

Khi Ethereum có chi phí giao dịch quá đắt đỏ - Tương lai cho layer2 ?

Với sự phát triển như vũ bão của Blockchain, ETH dường như đang quá tải và hệ quả là chi phí Gas đã lên đến 1000Gwei, phí để tạo những transaction phức tạp đã xấp xỉ 500$ . Và một giải pháp cứu cánh cho các sản phẩm Defi trên ETH chính là Layer2, và trong nhiệm vụ lần này Matic đang thể hiện khả năn

0 0 89

- vừa được xem lúc

Blockchain với Java - Tại sao không?

Cuộc cách mạng công nghiệp 4.0 ra đời kéo theo nhiều sự thay đổi và xu hướng mới được hình thành. Riêng đối với lĩnh vực CNTT cũng không nằm ngoài vùng ảnh hưởng mạnh mẽ. Chính làn sóng 4.

0 0 92

- vừa được xem lúc

Phân loại và tầm quan trọng của các node trong mạng blockchain

Trước khi đi vào phân loại và nêu rõ được tầm quan trọng của các node trọng mạng blockchain thì mình xin được trích dẫn khái niệm về blockchain từ Wikipedia như sau:. .

0 1 65

- vừa được xem lúc

Code Smart Contract bằng Assembly ?

Introduction. Hồi còn học trong ghế nhà trường bộ môn lập trình tốn nhiều não nhất của mình là code assembly. Nôm na thì bất cứ ngôn ngữ bậc cao nào như C , Go, Java,... được sinh ra để người dễ hiểu và dễ code , tuy nhiên chúng đều sẽ được compiled down xuống assembly một ngôn ngữ bậc thấp để máy h

0 0 58

- vừa được xem lúc

Dextool - Công cụ phân tích Decentralized Exchange tuyệt vời

. Trend Defi mặc dù đã bớt nhiệt nhưng những sản phẩm nổi bật của làn sóng này mang lại thì vẫn rất được người dùng ưa chuộng. Đặc biệt là các nền tảng Decentralized Exchange, tiêu biểu là Uniswap, SushiSwap, 1inch Exchange, FalconSwap,... Nhưng khi đã sử dụng các nền tảng DEx này mà không biết đến

0 0 106