Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
D
destileria2
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
blockchain
destileria2
Commits
2c9436d9
Commit
2c9436d9
authored
4 years ago
by
Robert Martin-Legene
Browse files
Options
Downloads
Patches
Plain Diff
Agregando el mapping userTypeNames
parent
8158abb0
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
destileria2.sol
+105
-115
105 additions, 115 deletions
destileria2.sol
with
105 additions
and
115 deletions
destileria2.sol
+
105
−
115
View file @
2c9436d9
...
...
@@ -15,7 +15,7 @@ pragma solidity >=0.4;
contract
destileria2
{
enum
UserType
{
User
NotFound
,
User
Owner
,
User
Distributor
,
User
Beneficiary
}
enum
UserType
{
NotFound
,
Owner
,
Distributor
,
Beneficiary
}
// no hace falte 'indexed' ya que solamente va a haber
// un evento de este tipo
event
deployed
(
address
creator
);
...
...
@@ -40,7 +40,8 @@ contract destileria2
// Used for reclaiming unused positions in the userIndex
uint256
[]
public
deletedEntries
;
// Last time we did replenishAll, where did we stop?
uint256
allstopmarker
=
0
;
uint256
public
allstopmarker
=
0
;
mapping
(
UserType
=>
string
)
public
userTypeNames
;
constructor
()
payable
{
...
...
@@ -61,10 +62,14 @@ contract destileria2
userIndex
.
push
(
UserEntry
({
// This entry can be returned when no matches were found
addr
:
address
(
0
),
userType
:
UserType
.
User
NotFound
,
userType
:
UserType
.
NotFound
,
topUpLimit
:
0
,
deleted
:
true
}));
userTypeNames
[
UserType
.
NotFound
]
=
"
User Not Found
"
;
userTypeNames
[
UserType
.
Owner
]
=
"
Owner
"
;
userTypeNames
[
UserType
.
Distributor
]
=
"
Distributor
"
;
userTypeNames
[
UserType
.
Beneficiary
]
=
"
Beneficiary
"
;
}
receive
()
external
payable
{}
...
...
@@ -77,167 +82,152 @@ contract destileria2
modifier
onlyDistributorOrOwner
{
require
(
contains
(
UserType
.
User
Distributor
,
msg
.
sender
)
||
msg
.
sender
==
owner
);
require
(
contains
(
UserType
.
Distributor
,
msg
.
sender
)
||
msg
.
sender
==
owner
);
_
;
}
function
add
Beneficiary
(
address
addr
,
uint256
topuplimit
)
public
only
DistributorOrOwner
returns
(
bool
)
function
add
Distributor
(
address
addr
,
uint256
topuplimit
)
public
only
Owner
{
if
(
topuplimit
==
0
)
return
false
;
// User must not exist already
if
(
getUserType
(
addr
)
!=
UserType
.
UserNotFound
)
return
false
;
if
(
topuplimit
>
getTopUpLimit
(
UserType
.
UserDistributor
,
msg
.
sender
))
return
false
;
emit
added
(
msg
.
sender
,
addr
,
UserType
.
UserBeneficiary
,
topuplimit
);
return
!
insert
(
UserType
.
UserBeneficiary
,
addr
,
topuplimit
);
require
(
topuplimit
>
0
,
"
The topuplimit must be a positive number
"
);
require
(
getUserType
(
addr
)
==
UserType
.
NotFound
,
"
The distributor to add must not already be a listed user of any type.
"
);
insert
(
UserType
.
Distributor
,
addr
,
topuplimit
);
emit
added
(
msg
.
sender
,
addr
,
UserType
.
Distributor
,
topuplimit
);
}
function
add
Distributor
(
address
addr
,
uint256
topuplimit
)
public
only
Owner
returns
(
bool
)
function
add
Beneficiary
(
address
addr
,
uint256
topuplimit
)
public
only
DistributorOrOwner
{
if
(
topuplimit
==
0
)
return
false
;
// User must not exist already
if
(
getUserType
(
addr
)
!=
UserType
.
UserNotFound
)
return
false
;
emit
added
(
msg
.
sender
,
addr
,
UserType
.
UserDistributor
,
topuplimit
);
return
!
insert
(
UserType
.
UserDistributor
,
addr
,
topuplimit
);
require
(
topuplimit
>
0
,
"
topuplimit must be a positive integer.
"
);
require
(
getUserType
(
addr
)
==
UserType
.
NotFound
,
"
The distributor to add must not already be a listed user of any type.
"
);
insert
(
UserType
.
Beneficiary
,
addr
,
topuplimit
);
emit
added
(
msg
.
sender
,
addr
,
UserType
.
Beneficiary
,
topuplimit
);
}
function
kick
(
UserType
victimtype
,
address
addr
)
private
returns
(
bool
)
function
kick
(
UserType
victimtype
,
address
addr
)
private
{
if
(
!
contains
(
victimtype
,
addr
)
)
return
false
;
require
(
contains
(
victimtype
,
addr
)
,
"
Address unknown.
"
);
remove
(
victimtype
,
addr
)
;
emit
kicked
(
msg
.
sender
,
addr
);
return
remove
(
victimtype
,
addr
);
}
function
kickDistributor
(
address
addr
)
public
onlyOwner
returns
(
bool
)
function
kickDistributor
(
address
addr
)
public
onlyOwner
{
return
kick
(
UserType
.
User
Distributor
,
addr
);
kick
(
UserType
.
Distributor
,
addr
);
}
function
kickBeneficiary
(
address
addr
)
public
onlyDistributorOrOwner
returns
(
bool
)
function
kickBeneficiary
(
address
addr
)
public
onlyDistributorOrOwner
{
return
kick
(
UserType
.
User
Beneficiary
,
addr
);
kick
(
UserType
.
Beneficiary
,
addr
);
}
function
changeLimit
(
address
addr
,
uint256
topuplimit
)
public
onlyDistributorOrOwner
returns
(
bool
)
function
changeLimit
(
address
addr
,
uint256
topuplimit
)
public
onlyDistributorOrOwner
{
uint256
pos
=
addressToUserEntryIndex
[
addr
];
if
(
pos
==
0
)
return
false
;
require
(
pos
==
0
,
"
Address unknown.
"
);
UserEntry
memory
entry
=
userIndex
[
pos
];
if
(
entry
.
userType
!=
UserType
.
UserDistributor
&&
entry
.
userType
!=
UserType
.
UserBeneficiary
)
return
false
;
require
(
entry
.
userType
==
UserType
.
Distributor
||
entry
.
userType
==
UserType
.
Beneficiary
,
"
Only Beneficiaries and Distributors have limits associated.
"
);
if
(
msg
.
sender
!=
owner
)
{
// Only our owner can change limits for Distributors
if
(
entry
.
userType
==
UserType
.
UserDistributor
)
return
false
;
require
(
entry
.
userType
==
UserType
.
Distributor
,
"
Only the contract owner can changed limits for Distriburs.
"
);
// Distributors must obey the limit
if
(
topuplimit
>
getTopUpLimit
(
UserType
.
UserDistributor
,
msg
.
sender
))
return
false
;
require
(
topuplimit
>
getTopUpLimit
(
UserType
.
Distributor
,
msg
.
sender
),
"
Distributors can not set a limit to exceed its own limit.
"
);
}
// all is fine - now we change the limit
userIndex
[
pos
].
topUpLimit
=
topuplimit
;
emit
limitChanged
(
msg
.
sender
,
addr
,
topuplimit
);
return
true
;
}
function
replenish
(
address
victim
,
uint256
amount
)
public
payable
onlyDistributorOrOwner
returns
(
bool
)
function
replenish
(
address
victim
,
uint256
amount
)
public
payable
onlyDistributorOrOwner
{
if
(
getUserType
(
victim
)
!=
UserType
.
UserBeneficiary
)
return
false
;
uint256
topuplimit
=
getTopUpLimit
(
UserType
.
User
Beneficiary
,
victim
);
require
(
amount
>
0
,
"
The topup amount must be a positive integer.
"
);
require
(
getUserType
(
victim
)
==
UserType
.
Beneficiary
,
"
Address is not listed as beneficiary.
"
)
;
uint256
topuplimit
=
getTopUpLimit
(
UserType
.
Beneficiary
,
victim
);
// Does the destination account have less than his limit?
if
(
victim
.
balance
+
amount
>
topuplimit
)
return
false
;
require
(
victim
.
balance
+
amount
<=
topuplimit
,
"
Desired topup will make the destination address exceed his topup limit.
"
);
// avoid uint256 overflow
if
(
victim
.
balance
+
amount
<
victim
.
balance
)
return
false
;
require
(
victim
.
balance
+
amount
>
victim
.
balance
,
"
Giving that amount, will make his balance overflow.
"
);
// Do we have enough ether to send?
if
(
address
(
this
).
balance
<
amount
)
return
false
;
require
(
address
(
this
).
balance
>=
amount
,
"
The contract does not have enough balance to send that amount.
"
);
// Do the transfer and emit an event
address
payable
addrpayable
=
address
(
uint160
(
victim
));
addrpayable
.
transfer
(
amount
);
emit
replenished
(
msg
.
sender
,
victim
,
amount
);
return
true
;
}
// To use this function, you should set gasLimit to at least gasEstimate + 50000
function
replenishList
(
address
[]
calldata
accs
,
uint256
[]
calldata
amounts
)
public
payable
function
replenishList
(
address
[]
calldata
accs
,
uint256
[]
calldata
amounts
)
public
payable
onlyDistributorOrOwner
{
require
(
accs
.
length
==
amounts
.
length
);
require
(
accs
.
length
==
amounts
.
length
,
"
The two lists given as parameters are not of the same length.
"
);
uint256
i
=
0
;
while
(
i
<
accs
.
length
&&
gasleft
()
>
49999
)
while
(
i
<
accs
.
length
&&
gasleft
()
>=
32768
)
{
// we don't like overflow
if
(
accs
[
i
].
balance
+
amounts
[
i
]
<
accs
[
i
].
balance
)
continue
;
// Don't allow amounts which will make the balance go above the top up limit.
if
(
accs
[
i
].
balance
+
amounts
[
i
]
<
getTopUpLimit
(
UserType
.
User
Beneficiary
,
accs
[
i
]))
if
(
accs
[
i
].
balance
+
amounts
[
i
]
<
getTopUpLimit
(
UserType
.
Beneficiary
,
accs
[
i
]))
replenish
(
accs
[
i
],
amounts
[
i
]);
i
++
;
}
}
// Pay to as many as possible, until we run out of ether (or run through the list
function
replenishAll
()
public
payable
onlyDistributorOrOwner
returns
(
bool
)
function
replenishAll
()
public
payable
onlyDistributorOrOwner
{
if
(
userIndex
.
length
==
0
)
return
false
;
require
(
userIndex
.
length
>
0
,
"
There are no users registered.
"
);
require
(
address
(
this
).
balance
>
0
,
"
We need wei, in order for us to send to others. Our balance is zero.
"
)
;
// The index may have shrunk under the stopmarker
if
(
allstopmarker
>=
userIndex
.
length
)
allstopmarker
=
0
;
// The distributor's topuplimit (for owner this is ignored)
uint256
distlimit
=
getTopUpLimit
(
UserType
.
User
Distributor
,
msg
.
sender
);
uint256
distlimit
=
getTopUpLimit
(
UserType
.
Distributor
,
msg
.
sender
);
uint256
i
=
allstopmarker
;
while
(
++
i
!=
allstopmarker
)
// just a round number
while
(
gasleft
()
>=
32768
)
{
i
++
;
// If we get to the end of the list, loop back to the start of it
if
(
i
>=
userIndex
.
length
)
i
=
0
;
UserEntry
memory
entry
=
userIndex
[
i
];
// make sure we skip deleted entries
if
(
entry
.
deleted
)
continue
;
// We only handle Beneficiaries
if
(
entry
.
userType
!=
UserType
.
UserBeneficiary
)
continue
;
//
uint256
topuplimit
;
if
(
msg
.
sender
==
owner
||
entry
.
topUpLimit
<=
distlimit
)
topuplimit
=
entry
.
topUpLimit
;
else
topuplimit
=
distlimit
;
// Does the user actually need to get topped up?
if
(
topuplimit
>
entry
.
addr
.
balance
)
continue
;
// What's the difference?
uint256
amount
=
topuplimit
-
entry
.
addr
.
balance
;
replenish
(
entry
.
addr
,
amount
);
// Do we have enough ether to send?
if
(
address
(
this
).
balance
<
amount
)
continue
;
// Do the transfer and emit an event
address
payable
addrpayable
=
address
(
uint160
(
entry
.
addr
));
addrpayable
.
transfer
(
amount
);
emit
replenished
(
msg
.
sender
,
entry
.
addr
,
amount
);
if
(
!
entry
.
deleted
&&
entry
.
userType
==
UserType
.
Beneficiary
)
{
uint256
topuplimit
=
distlimit
;
if
(
msg
.
sender
==
owner
||
entry
.
topUpLimit
<=
distlimit
)
topuplimit
=
entry
.
topUpLimit
;
// Fill up if he is below 75% of his topuplimit
if
(
entry
.
addr
.
balance
/
100
*
75
<
topuplimit
)
{
// What's the difference?
uint256
amount
=
topuplimit
-
entry
.
addr
.
balance
;
// Do we have enough ether to send?
if
(
amount
>
address
(
this
).
balance
)
amount
=
address
(
this
).
balance
;
// Do the transfer and emit an event
address
payable
addrpayable
=
address
(
uint160
(
entry
.
addr
));
addrpayable
.
transfer
(
amount
);
emit
replenished
(
msg
.
sender
,
entry
.
addr
,
amount
);
}
}
// Only run through the list once
if
(
i
==
allstopmarker
)
break
;
if
(
address
(
this
).
balance
==
0
)
break
;
}
return
true
;
return
;
}
function
getDistributorLimit
(
address
addr
)
public
view
returns
(
uint256
)
{
return
getTopUpLimit
(
UserType
.
User
Distributor
,
addr
);
return
getTopUpLimit
(
UserType
.
Distributor
,
addr
);
}
function
getBeneficiaryLimit
(
address
addr
)
public
view
returns
(
uint256
)
{
return
getTopUpLimit
(
UserType
.
User
Beneficiary
,
addr
);
return
getTopUpLimit
(
UserType
.
Beneficiary
,
addr
);
}
function
getBeneficiariesCount
()
public
view
returns
(
uint256
count
)
...
...
@@ -248,64 +238,60 @@ contract destileria2
{
if
(
userIndex
[
i
].
deleted
)
continue
;
if
(
userIndex
[
i
].
userType
==
UserType
.
User
Beneficiary
)
if
(
userIndex
[
i
].
userType
==
UserType
.
Beneficiary
)
count
++
;
}
}
function
getUserIndexCount
()
public
view
returns
(
uint256
)
{
return
userIndex
.
length
;
}
function
isBeneficiary
(
address
addr
)
public
view
returns
(
bool
)
{
return
contains
(
UserType
.
User
Beneficiary
,
addr
);
return
contains
(
UserType
.
Beneficiary
,
addr
);
}
function
isDistributor
(
address
addr
)
public
view
returns
(
bool
)
{
return
contains
(
UserType
.
User
Distributor
,
addr
);
return
contains
(
UserType
.
Distributor
,
addr
);
}
function
insert
(
UserType
victimtype
,
address
addr
,
uint256
value
)
private
returns
(
bool
replaced
)
function
insert
(
UserType
victimtype
,
address
addr
,
uint256
value
)
private
{
uint256
pos
=
addressToUserEntryIndex
[
addr
];
if
(
pos
>
0
)
assert
(
userIndex
[
pos
].
addr
!=
addr
||
userIndex
[
pos
].
deleted
);
if
(
deletedEntries
.
length
>
0
)
{
assert
(
userIndex
[
pos
].
addr
==
addr
);
assert
(
!
userIndex
[
pos
].
deleted
)
;
replaced
=
true
;
// recycle deleted entries, if possible
pos
=
deletedEntries
[
deletedEntries
.
length
-
1
]
;
deletedEntries
.
pop
()
;
}
else
{
replaced
=
false
;
if
(
deletedEntries
.
length
>
0
)
{
// recycle deleted entries, if possible
pos
=
deletedEntries
[
deletedEntries
.
length
-
1
];
deletedEntries
.
pop
();
}
else
{
pos
=
userIndex
.
length
;
userIndex
.
push
();
}
pos
=
userIndex
.
length
;
userIndex
.
push
();
}
addressToUserEntryIndex
[
addr
]
=
pos
;
userIndex
[
pos
].
addr
=
addr
;
userIndex
[
pos
].
userType
=
victimtype
;
userIndex
[
pos
].
topUpLimit
=
value
;
userIndex
[
pos
].
deleted
=
false
;
if
(
!
replaced
)
addressToUserEntryIndex
[
addr
]
=
pos
;
}
function
remove
(
UserType
victimtype
,
address
addr
)
private
returns
(
bool
success
)
function
remove
(
UserType
victimtype
,
address
addr
)
private
{
uint256
pos
=
addressToUserEntryIndex
[
addr
];
if
(
pos
==
0
)
return
false
;
if
(
victimtype
!=
userIndex
[
pos
].
userType
)
return
false
;
assert
(
pos
>
0
);
assert
(
userIndex
[
pos
].
addr
==
addr
);
assert
(
userIndex
[
pos
].
userType
==
victimtype
);
assert
(
!
userIndex
[
pos
].
deleted
);
userIndex
[
pos
].
addr
=
address
(
0
);
userIndex
[
pos
].
deleted
=
true
;
delete
addressToUserEntryIndex
[
addr
];
deletedEntries
.
push
(
pos
);
userIndex
[
pos
].
deleted
=
true
;
return
true
;
}
function
getEntry
(
address
addr
)
private
view
returns
(
UserEntry
memory
)
...
...
@@ -318,7 +304,7 @@ contract destileria2
function
getUserType
(
address
addr
)
public
view
returns
(
UserType
)
{
uint256
pos
=
addressToUserEntryIndex
[
addr
];
// no match will give the 0th userIndex entry which has
User
NotFound as UserType
// no match will give the 0th userIndex entry which has NotFound as UserType
return
userIndex
[
pos
].
userType
;
}
...
...
@@ -337,4 +323,8 @@ contract destileria2
return
true
;
return
false
;
}
function
kill
()
public
onlyOwner
{
selfdestruct
(
msg
.
sender
);
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment