People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!
fillRelay() and the dataworker will handle it.deposit and fill. The deposit is what the relayer does and the fill is what the dataworker does, after something has happened to the initial fill. Being able to tie a fill to a deposit is important to ensuring that double spends don't occur - both for the on chain and off chain infrastructure.validateFillForDeposit Fill() filters all recent fills to find the proper deposit for it. getValidUnfilledAmountForDDeposit() obtains the previous fills for the deposit against depositsWithBlockNumbers(). Additionally, there is a function that handles updates() that were being made to the transfer.relayerFeePct field would be updated for a sped up deposit within the local object. Since the hash of the original object and the new object were different, it saw that as a valid fill! The tying together portion of the code has been broken.relayerFeePct on the source chain. This will get the relayer to see the deposit to NOT see it as a slow relay anymore.relayerFeePct. Personally, I don't like the client side fix very much; I feel like doing something with the hash would make more sense. Unfortunately, there are times where hashing too many things is just as bad as hashing too few.