Skip to content

Commit cdeda84

Browse files
blperez01bohendo
authored andcommitted
Changed missing constructor to more sensible name
1 parent 2cffb04 commit cdeda84

File tree

3 files changed

+195
-0
lines changed

3 files changed

+195
-0
lines changed

wrong_constructor_name/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Missing constructor
2+
3+
If the constructor of a smart contract is not present (or not spelled the same way as the contract name), it is callable by anyone.
4+
5+
## Attack
6+
Anyone can call the function that was supposed to be the constructor.
7+
As a result anyone can change the state variables initialized in this function.
8+
9+
## Mitigations
10+
11+
- Use `constructor` instead of a named constructor
12+
13+
## Examples
14+
- [Rubixi](Rubixi_source_code/Rubixi.sol) uses `DynamicPyramid` instead of `Rubixi` as a constructor
15+
- An [incorrectly named constructor](Missing.sol)
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// 0xe82719202e5965Cf5D9B6673B7503a3b92DE20be#code
2+
pragma solidity ^0.4.15;
3+
4+
contract Rubixi {
5+
6+
//Declare variables for storage critical to contract
7+
uint private balance = 0;
8+
uint private collectedFees = 0;
9+
uint private feePercent = 10;
10+
uint private pyramidMultiplier = 300;
11+
uint private payoutOrder = 0;
12+
13+
address private creator;
14+
15+
//Sets creator
16+
function DynamicPyramid() {
17+
creator = msg.sender;
18+
}
19+
20+
modifier onlyowner {
21+
if (msg.sender == creator) _;
22+
}
23+
24+
struct Participant {
25+
address etherAddress;
26+
uint payout;
27+
}
28+
29+
Participant[] private participants;
30+
31+
//Fallback function
32+
function() {
33+
init();
34+
}
35+
36+
//init function run on fallback
37+
function init() private {
38+
//Ensures only tx with value of 1 ether or greater are processed and added to pyramid
39+
if (msg.value < 1 ether) {
40+
collectedFees += msg.value;
41+
return;
42+
}
43+
44+
uint _fee = feePercent;
45+
//50% fee rebate on any ether value of 50 or greater
46+
if (msg.value >= 50 ether) _fee /= 2;
47+
48+
addPayout(_fee);
49+
}
50+
51+
//Function called for valid tx to the contract
52+
function addPayout(uint _fee) private {
53+
//Adds new address to participant array
54+
participants.push(Participant(msg.sender, (msg.value * pyramidMultiplier) / 100));
55+
56+
//These statements ensure a quicker payout system to later pyramid entrants, so the pyramid has a longer lifespan
57+
if (participants.length == 10) pyramidMultiplier = 200;
58+
else if (participants.length == 25) pyramidMultiplier = 150;
59+
60+
// collect fees and update contract balance
61+
balance += (msg.value * (100 - _fee)) / 100;
62+
collectedFees += (msg.value * _fee) / 100;
63+
64+
//Pays earlier participiants if balance sufficient
65+
while (balance > participants[payoutOrder].payout) {
66+
uint payoutToSend = participants[payoutOrder].payout;
67+
participants[payoutOrder].etherAddress.send(payoutToSend);
68+
69+
balance -= participants[payoutOrder].payout;
70+
payoutOrder += 1;
71+
}
72+
}
73+
74+
//Fee functions for creator
75+
function collectAllFees() onlyowner {
76+
if (collectedFees == 0) throw;
77+
78+
creator.send(collectedFees);
79+
collectedFees = 0;
80+
}
81+
82+
function collectFeesInEther(uint _amt) onlyowner {
83+
_amt *= 1 ether;
84+
if (_amt > collectedFees) collectAllFees();
85+
86+
if (collectedFees == 0) throw;
87+
88+
creator.send(_amt);
89+
collectedFees -= _amt;
90+
}
91+
92+
function collectPercentOfFees(uint _pcent) onlyowner {
93+
if (collectedFees == 0 || _pcent > 100) throw;
94+
95+
uint feesToCollect = collectedFees / 100 * _pcent;
96+
creator.send(feesToCollect);
97+
collectedFees -= feesToCollect;
98+
}
99+
100+
//Functions for changing variables related to the contract
101+
function changeOwner(address _owner) onlyowner {
102+
creator = _owner;
103+
}
104+
105+
function changeMultiplier(uint _mult) onlyowner {
106+
if (_mult > 300 || _mult < 120) throw;
107+
108+
pyramidMultiplier = _mult;
109+
}
110+
111+
function changeFeePercentage(uint _fee) onlyowner {
112+
if (_fee > 10) throw;
113+
114+
feePercent = _fee;
115+
}
116+
117+
//Functions to provide information to end-user using JSON interface or other interfaces
118+
function currentMultiplier() constant returns(uint multiplier, string info) {
119+
multiplier = pyramidMultiplier;
120+
info = 'This multiplier applies to you as soon as transaction is received, may be lowered to hasten payouts or increased if payouts are fast enough. Due to no float or decimals, multiplier is x100 for a fractional multiplier e.g. 250 is actually a 2.5x multiplier. Capped at 3x max and 1.2x min.';
121+
}
122+
123+
function currentFeePercentage() constant returns(uint fee, string info) {
124+
fee = feePercent;
125+
info = 'Shown in % form. Fee is halved(50%) for amounts equal or greater than 50 ethers. (Fee may change, but is capped to a maximum of 10%)';
126+
}
127+
128+
function currentPyramidBalanceApproximately() constant returns(uint pyramidBalance, string info) {
129+
pyramidBalance = balance / 1 ether;
130+
info = 'All balance values are measured in Ethers, note that due to no decimal placing, these values show up as integers only, within the contract itself you will get the exact decimal value you are supposed to';
131+
}
132+
133+
function nextPayoutWhenPyramidBalanceTotalsApproximately() constant returns(uint balancePayout) {
134+
balancePayout = participants[payoutOrder].payout / 1 ether;
135+
}
136+
137+
function feesSeperateFromBalanceApproximately() constant returns(uint fees) {
138+
fees = collectedFees / 1 ether;
139+
}
140+
141+
function totalParticipants() constant returns(uint count) {
142+
count = participants.length;
143+
}
144+
145+
function numberOfParticipantsWaitingForPayout() constant returns(uint count) {
146+
count = participants.length - payoutOrder;
147+
}
148+
149+
function participantDetails(uint orderInPyramid) constant returns(address Address, uint Payout) {
150+
if (orderInPyramid <= participants.length) {
151+
Address = participants[orderInPyramid].etherAddress;
152+
Payout = participants[orderInPyramid].payout / 1 ether;
153+
}
154+
}
155+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
pragma solidity ^0.4.15;
2+
3+
contract Missing{
4+
address private owner;
5+
6+
modifier onlyowner {
7+
require(msg.sender==owner);
8+
_;
9+
}
10+
11+
// The name of the constructor should be Missing
12+
// Anyone can call the IamMissing once the contract is deployed
13+
function IamMissing()
14+
public
15+
{
16+
owner = msg.sender;
17+
}
18+
19+
function withdraw()
20+
public
21+
onlyowner
22+
{
23+
owner.transfer(this.balance);
24+
}
25+
}

0 commit comments

Comments
 (0)