Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
nucleo
Manage
Activity
Members
Labels
Plan
Issues
4
Issue boards
Milestones
Wiki
Code
Merge requests
1
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor 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
nucleo
Commits
42053f6d
Commit
42053f6d
authored
6 years ago
by
Robert Martin-Legene
Browse files
Options
Downloads
Patches
Plain Diff
Updated the Distillery SC to also emit events.
parent
0b4cb2b4
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/Distillery.sol
+72
-44
72 additions, 44 deletions
src/Distillery.sol
with
72 additions
and
44 deletions
src/Distillery.sol
+
72
−
44
View file @
42053f6d
...
...
@@ -5,7 +5,7 @@ contract Distillery {
address
owner
;
struct
Allowances
{
address
beneficiary
;
uint
256
value
;
uint
topuplimit
;
}
Allowances
[]
thelist
;
// We use distpos to remember where we were stopped processing last time
...
...
@@ -16,7 +16,11 @@ contract Distillery {
// that some would have first priority in getting ether at every invocation
// So we continue checking the list from the same place where we left off
// at the previous invocation of distribute()
uint256
distpos
;
uint
distpos
;
event
distributeStartedBy
(
address
activator
);
event
setAllowance
(
address
subject
,
uint
amount
);
event
xfrAllowance
(
address
subject
,
uint
amount
);
constructor
()
public
payable
{
owner
=
msg
.
sender
;
...
...
@@ -26,83 +30,107 @@ contract Distillery {
_
;
}
// Using this function, you can find out how long thelist is.
function
numberOfBeneficiaries
()
public
view
returns
(
uint
256
)
{
function
numberOfBeneficiaries
()
public
view
returns
(
uint
)
{
return
thelist
.
length
;
}
// Using this function, you get the address and
"value"
at a given position in thelist.
function
atPosition
(
uint
256
idx
)
public
view
returns
(
address
,
uint
256
)
{
// Using this function, you get the address and
topuplimit
at a given position in thelist.
function
atPosition
(
uint
idx
)
public
view
returns
(
address
,
uint
)
{
require
(
idx
<=
thelist
.
length
,
"
There are not that many addresses in the list.
"
);
return
(
thelist
[
idx
].
beneficiary
,
thelist
[
idx
].
value
);
return
(
thelist
[
idx
].
beneficiary
,
thelist
[
idx
].
topuplimit
);
}
// Returns a (signed) position of where an address can be found in thelist.
// Or returns -1 if the address is not found in thelist.
function
_beneficiaryPosition
(
address
beneficiary
)
internal
view
returns
(
int256
)
{
uint256
pos
=
thelist
.
length
&
0x7fffffffffffffffffffffffffffffff
;
// Returns a position +1 of where an address can be found in thelist.
// Or returns 0 if the address is not found in thelist.
// 0 : not found
// 1 : first position
function
_beneficiaryPosition
(
address
beneficiary
)
internal
view
returns
(
uint
)
{
uint
pos
=
thelist
.
length
;
while
(
pos
--
>
0
)
if
(
beneficiary
==
thelist
[
pos
].
beneficiary
)
return
int256
(
pos
&
0x7fffffffffffffffffffffffffffffff
)
;
return
-
1
;
return
pos
+
1
;
return
0
;
}
// This function returns the "allowance" that a given address is set to.
// Using this function, you don't have to cycle through atPosition() until
// you find the address you want to know about.
function
getEtherAllowance
(
address
beneficiary
)
public
view
returns
(
uint256
)
{
int
256
pos
=
_beneficiaryPosition
(
beneficiary
);
if
(
pos
==
-
1
)
u
int
pos
=
_beneficiaryPosition
(
beneficiary
);
if
(
pos
==
0
)
return
0
;
return
thelist
[
uint256
(
pos
)].
value
;
return
thelist
[
pos
-
1
].
topuplimit
;
}
// This admin (ownerOnly) function allows the creator of the contract to
// add/change/delete "allowances" per address.
function
setEtherAllowance
(
address
beneficiary
,
uint256
value
)
public
onlyOwner
{
int256
pos
=
_beneficiaryPosition
(
beneficiary
);
if
(
value
>
0
)
{
if
(
pos
==
-
1
)
// Add the address to thelist if it was not already there
thelist
.
push
(
Allowances
(
beneficiary
,
value
)
);
else
// Simple update the value of this address
thelist
[
uint256
(
pos
)].
value
=
value
;
function
setEtherAllowance
(
address
beneficiary
,
uint256
topuplimit
)
public
onlyOwner
{
uint
pos
=
_beneficiaryPosition
(
beneficiary
);
// Not found and trying to delete beneficiary? Just return immediately.
if
(
pos
==
0
&&
topuplimit
==
0
)
return
;
emit
setAllowance
(
beneficiary
,
topuplimit
);
// not found
if
(
pos
==
0
)
{
if
(
topuplimit
>
0
)
// Add the address to thelist because it was not already there
thelist
.
push
(
Allowances
(
beneficiary
,
topuplimit
)
);
return
;
}
else
{
// The beneficiary is set to have 0 Ether, so we
// delete the beneficiary from the list
uint
i
=
uint256
(
pos
)
+
1
;
while
(
i
++
<
thelist
.
length
)
thelist
[
i
]
=
thelist
[
i
+
1
];
// If distpos was past the position that we removed,
// then move that back one.
if
(
distpos
>
uint256
(
pos
)
)
distpos
--
;
// Shorten the list
thelist
.
length
--
;
}
// Now use a properly zero-indexed pos
pos
--
;
//
if
(
topuplimit
>
0
)
{
// Simple update the topuplimit of this address
thelist
[
pos
].
topuplimit
=
topuplimit
;
return
;
}
// The beneficiary is set to have 0 Ether, so we
// delete the beneficiary from the list
uint
i
=
pos
;
while
(
i
++
<
thelist
.
length
)
thelist
[
i
-
1
]
=
thelist
[
i
];
// Shorten the list
thelist
.
length
--
;
// If distpos was past the position that we removed,
// then move that back one.
if
(
distpos
>=
pos
)
distpos
--
;
}
function
selfDestruct
()
public
onlyOwner
{
selfdestruct
(
owner
);
}
function
mayDistribute
()
public
view
returns
(
bool
)
{
return
msg
.
sender
==
owner
;
}
function
distribute
()
external
{
uint256
listlength
=
thelist
.
length
;
require
(
mayDistribute
(),
"
You are not authorized to activate the distribution functionality.
"
);
emit
distributeStartedBy
(
msg
.
sender
);
// Is there anything to do at all
uint
listlength
=
thelist
.
length
;
if
(
listlength
==
0
)
return
;
// Has the list gotten shorter since we we were last time?
// This shouldn't happen, but it's better to be safe than to be sorry.
if
(
distpos
>=
listlength
)
distpos
=
0
;
uint
256
wheretostop
=
distpos
;
distpos
=
0
;
uint
wheretostop
=
distpos
;
while
(
gasleft
()
>
54321
)
{
// Did we get to the end of the list, then start over
if
(
++
distpos
>=
listlength
)
distpos
=
0
;
uint256
balance
=
thelist
[
distpos
].
beneficiary
.
balance
;
uint256
value
=
thelist
[
distpos
].
value
;
if
(
balance
<
value
&&
(
value
+
diff
)
>
0
)
distpos
=
0
;
uint
blockchainbalance
=
thelist
[
distpos
].
beneficiary
.
balance
;
uint
topuplimit
=
thelist
[
distpos
].
topuplimit
;
uint
diff
=
topuplimit
-
blockchainbalance
;
// Don't top up anyone, if they still more than 90% of their allowance.
if
(
blockchainbalance
>
topuplimit
*
9
/
10
)
diff
=
0
;
if
(
diff
>
0
)
{
uint256
diff
=
value
-
balance
;
// we use send() instead of transfer(), because
// transfer() can throw(), and we don't want
// to stop processing because of a single error.
// -
// Use || true to avoid warnings from the compiler.
emit
xfrAllowance
(
thelist
[
distpos
].
beneficiary
,
diff
);
thelist
[
distpos
].
beneficiary
.
send
(
diff
)
||
true
;
}
if
(
wheretostop
==
distpos
)
...
...
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