This:
$(OBJS) : $(SRCS)
expands to this:
bin/a.o bin/b.o bin/c.o bin/d.o : srcs/foo/a.c srcs/foo/b.c srcs/bar/c.c srcs/bar/d.c
which is interpreted by make the same way as this:
bin/a.o : srcs/foo/a.c srcs/foo/b.c srcs/bar/c.c srcs/bar/d.c
bin/b.o : srcs/foo/a.c srcs/foo/b.c srcs/bar/c.c srcs/bar/d.c
bin/c.o : srcs/foo/a.c srcs/foo/b.c srcs/bar/c.c srcs/bar/d.c
bin/d.o : srcs/foo/a.c srcs/foo/b.c srcs/bar/c.c srcs/bar/d.c
so for every object file the list of source files is the same, and so the first source file (what $< expands to) is always the same file.
Make is not going to go through the targets and prerequisites and "match them up" one to one, somehow. That's not how it works, and such a thing would not be feasible anyway.
This is why pattern rules and VPATH were invented:
VPATH = srcs/foo srcs/bar
bin/%.o : %.c
gcc -c $< -o $@
Of course, this is quite dangerous since if you ever have the same source filename in two different directories, you'll get conflicts in the object files. Most people don't do this: they replicate the source directory in the object directory (so you'd have obj/foo/a.o and obj/bar/c.o). If you do that you don't need VPATH, you can just use:
bin/%.o : src/%.c
gcc -c $< -o $@
Maybe with a @mkdir -p $(@D) thrown in there to create the directories first.